mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
This commit is contained in:
parent
60d82283ed
commit
ed0cce499d
11 changed files with 173 additions and 32 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,7 +1,7 @@
|
|||
.DS_Store
|
||||
node_modules
|
||||
src/bower_components
|
||||
**/styles/*.css
|
||||
**/*.css
|
||||
trash
|
||||
build
|
||||
target
|
||||
|
|
|
@ -5,11 +5,19 @@
|
|||
{{dash.title}}
|
||||
</span>
|
||||
|
||||
<form class="fill inline-form" ng-submit="filterResults()">
|
||||
<input placeholder="Filter..." type="text" class="form-control" ng-model="state.query">
|
||||
<button class="btn btn-default" type="submit">
|
||||
<span class="fa fa-search"></span>
|
||||
</button>
|
||||
<form class="fill inline-form" ng-submit="filterResults()" name="queryInput">
|
||||
<div class="input-group"
|
||||
ng-class="queryInput.$invalid ? 'has-error' : ''">
|
||||
<input query-input
|
||||
placeholder="Filter..."
|
||||
type="text"
|
||||
class="form-control"
|
||||
ng-model="state.query">
|
||||
<button class="btn btn-default" type="submit"
|
||||
ng-disabled="queryInput.$invalid">
|
||||
<span class="fa fa-search"></span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="button-group">
|
||||
|
|
|
@ -85,11 +85,7 @@ define(function (require) {
|
|||
function updateQueryOnRootSource() {
|
||||
if ($state.query) {
|
||||
dash.searchSource.set('filter', {
|
||||
query: {
|
||||
query_string: {
|
||||
query: $state.query
|
||||
}
|
||||
}
|
||||
query: $state.query
|
||||
});
|
||||
} else {
|
||||
dash.searchSource.set('filter', null);
|
||||
|
|
|
@ -15,6 +15,7 @@ define(function (require) {
|
|||
require('filters/moment');
|
||||
require('components/courier/courier');
|
||||
require('components/index_patterns/index_patterns');
|
||||
require('components/query_input/query_input');
|
||||
require('components/state_management/app_state');
|
||||
require('services/timefilter');
|
||||
|
||||
|
@ -70,7 +71,7 @@ define(function (require) {
|
|||
var defaultFormat = courier.indexPatterns.fieldFormats.defaultByType.string;
|
||||
|
||||
var stateDefaults = {
|
||||
query: initialQuery ? initialQuery.query_string.query : '',
|
||||
query: initialQuery || '',
|
||||
columns: ['_source'],
|
||||
index: config.get('defaultIndex'),
|
||||
interval: 'auto'
|
||||
|
@ -291,11 +292,7 @@ define(function (require) {
|
|||
}
|
||||
return sort;
|
||||
})
|
||||
.query(!$state.query ? null : {
|
||||
query_string: {
|
||||
query: $state.query
|
||||
}
|
||||
});
|
||||
.query(!$state.query ? null : $state.query);
|
||||
|
||||
// get the current indexPattern
|
||||
var indexPattern = $scope.searchSource.get('index');
|
||||
|
|
|
@ -1,9 +1,18 @@
|
|||
<div ng-controller="discover">
|
||||
<navbar>
|
||||
<form class="fill inline-form" ng-submit="fetch()">
|
||||
<input placeholder="Search..." type="text" class="form-control" ng-model="state.query">
|
||||
<button type="submit"><span class="fa fa-search"></span></button>
|
||||
<button type="button" ng-click="resetQuery()"><span class="fa fa-ban"></span></button>
|
||||
<form class="fill inline-form" ng-submit="fetch()" name="discoverSearch">
|
||||
<div class="input-group"
|
||||
ng-class="discoverSearch.$invalid ? 'has-error' : ''">
|
||||
<input query-input="searchSource"
|
||||
ng-model="state.query"
|
||||
placeholder="Search..."
|
||||
type="text"
|
||||
class="form-control">
|
||||
<button type="submit"
|
||||
ng-disabled="discoverSearch.$invalid">
|
||||
<span class="fa fa-search"></span></button>
|
||||
<button type="button" ng-click="resetQuery()"><span class="fa fa-ban"></span></button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="button-group">
|
||||
|
|
|
@ -228,7 +228,7 @@ define(function (require) {
|
|||
delete vis.savedSearchId;
|
||||
|
||||
var q = vis.searchSource.get('query');
|
||||
$state.query = _.isObject(q) ? q.query_string.query : q;
|
||||
$state.query = q;
|
||||
|
||||
var parent = vis.searchSource.parent();
|
||||
// we will copy over all state minus the "aggs"
|
||||
|
@ -249,7 +249,7 @@ define(function (require) {
|
|||
delete $state.query;
|
||||
} else {
|
||||
var q = $state.query || vis.searchSource.get('query');
|
||||
$state.query = _.isObject(q) ? q.query_string.query : q;
|
||||
$state.query = q;
|
||||
}
|
||||
|
||||
// init
|
||||
|
|
|
@ -17,13 +17,19 @@
|
|||
<i class="fa fa-chain-broken"></i> Unlinked!
|
||||
</div>
|
||||
|
||||
<form ng-submit="doVisualize()" class="inline-form">
|
||||
<input
|
||||
placeholder="Search..."
|
||||
type="text"
|
||||
class="form-control"
|
||||
ng-model="state.query">
|
||||
<button class="btn btn-default" type="submit"><span class="fa fa-search"></span></button>
|
||||
<form ng-submit="doVisualize()" class="inline-form" name="queryInput">
|
||||
<div class="input-group"
|
||||
ng-class="queryInput.$invalid ? 'has-error' : ''">
|
||||
<input query-input="vis.searchSource"
|
||||
placeholder="Search..."
|
||||
type="text"
|
||||
class="form-control"
|
||||
ng-model="state.query">
|
||||
<button class="btn btn-default" type="submit"
|
||||
ng-disabled="queryInput.$invalid">
|
||||
<span class="fa fa-search"></span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
|
112
src/kibana/components/query_input/query_input.js
Normal file
112
src/kibana/components/query_input/query_input.js
Normal file
|
@ -0,0 +1,112 @@
|
|||
define(function (require) {
|
||||
var _ = require('lodash');
|
||||
var $ = require('jquery');
|
||||
|
||||
require('css!components/query_input/query_input.css');
|
||||
|
||||
require('modules')
|
||||
.get('kibana')
|
||||
.directive('queryInput', function (es, $compile, timefilter, configFile) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
require: 'ngModel',
|
||||
scope: {
|
||||
'ngModel': '=',
|
||||
'queryInput': '=?',
|
||||
},
|
||||
link: function ($scope, elem, attr, ngModel) {
|
||||
|
||||
// track request so we can abort it if needed
|
||||
var request = {};
|
||||
|
||||
var errorElem = $('<i class="fa fa-ban input-query-error"></i>').hide();
|
||||
|
||||
var init = function () {
|
||||
elem.after(errorElem);
|
||||
validater($scope.ngModel);
|
||||
};
|
||||
|
||||
var validater = function (query) {
|
||||
var index, type;
|
||||
|
||||
var error = function (resp) {
|
||||
ngModel.$setValidity('queryInput', false);
|
||||
|
||||
errorElem.attr('tooltip', resp.explanations && resp.explanations[0] ?
|
||||
resp.explanations[0].error : undefined);
|
||||
|
||||
// Compile is needed for the tooltip
|
||||
$compile(errorElem)($scope);
|
||||
errorElem.show();
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
var success = function (resp) {
|
||||
if (resp.valid) {
|
||||
ngModel.$setValidity('queryInput', true);
|
||||
errorElem.hide();
|
||||
return query;
|
||||
} else {
|
||||
return error(resp);
|
||||
}
|
||||
};
|
||||
|
||||
if ($scope.queryInput) {
|
||||
index = $scope.queryInput.get('index').toIndexList();
|
||||
} else {
|
||||
index = configFile.kibanaIndex;
|
||||
type = '__kibanaQueryValidator';
|
||||
}
|
||||
|
||||
if (request.abort) request.abort();
|
||||
|
||||
request = es.indices.validateQuery({
|
||||
index: index,
|
||||
type: type,
|
||||
explain: true,
|
||||
ignoreUnavailable: true,
|
||||
body: {
|
||||
query: query || { match_all: {} }
|
||||
}
|
||||
}).then(success, error);
|
||||
};
|
||||
|
||||
var debouncedValidator = _.debounce(validater, 300);
|
||||
|
||||
|
||||
// What should I make with the input from the user?
|
||||
var fromUser = function (text) {
|
||||
try {
|
||||
return JSON.parse(text);
|
||||
} catch (e) {
|
||||
return {
|
||||
query_string: {
|
||||
query: text || '*'
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// How should I present the data back to the user in the input field?
|
||||
var toUser = function (text) {
|
||||
if (_.isString(text)) return text;
|
||||
if (_.isObject(text)) {
|
||||
if (text.query_string) return text.query_string.query;
|
||||
return JSON.stringify(text);
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
ngModel.$parsers.push(fromUser);
|
||||
ngModel.$formatters.push(toUser);
|
||||
|
||||
// Use a model watch instead of parser/formatter. Debounced anyway. Parsers require the
|
||||
// user to actually enter input, which may not happen if the back button is clicked
|
||||
$scope.$watch('ngModel', debouncedValidator);
|
||||
|
||||
init();
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
11
src/kibana/components/query_input/query_input.less
Normal file
11
src/kibana/components/query_input/query_input.less
Normal file
|
@ -0,0 +1,11 @@
|
|||
@import (reference) "../../styles/_bootstrap.less";
|
||||
@import (reference) "../../styles/theme/_theme.less";
|
||||
@import (reference) "../../styles/_variables.less";
|
||||
|
||||
i.query-input-error {
|
||||
position: absolute;
|
||||
margin-left: -25px;
|
||||
color: @brand-danger;
|
||||
margin-top: 10px;
|
||||
z-index: 5;
|
||||
}
|
|
@ -76,7 +76,8 @@ navbar {
|
|||
|
||||
// horizontal group of buttons/form elements
|
||||
.button-group,
|
||||
.inline-form {
|
||||
.inline-form .input-group {
|
||||
margin-bottom: 0px;
|
||||
.display(flex);
|
||||
|
||||
> * {
|
||||
|
@ -90,7 +91,7 @@ navbar {
|
|||
}
|
||||
}
|
||||
|
||||
.inline-form {
|
||||
.inline-form .input-group {
|
||||
input {
|
||||
height: auto;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ var bc = require('path').join(__dirname, '../../src/bower_components');
|
|||
module.exports = {
|
||||
src: {
|
||||
src: [
|
||||
'<%= src %>/kibana/components/*/*.less',
|
||||
'<%= src %>/kibana/apps/dashboard/styles/main.less',
|
||||
'<%= src %>/kibana/apps/discover/styles/main.less',
|
||||
'<%= src %>/kibana/apps/settings/styles/main.less',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue