mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
Merge branch 'master' into feature/custom-toaster-banner
This commit is contained in:
commit
f36cb6524a
288 changed files with 7169 additions and 5176 deletions
36
.github/ISSUE_TEMPLATE.md
vendored
Normal file
36
.github/ISSUE_TEMPLATE.md
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
<!--
|
||||
GitHub is reserved for bug reports and feature requests. The best place
|
||||
to ask a general question is at the Elastic Discourse forums at
|
||||
https://discuss.elastic.co. If you are in fact posting a bug report or
|
||||
a feature request, please include one and only one of the below blocks
|
||||
in your new issue.
|
||||
-->
|
||||
|
||||
<!--
|
||||
If you are filing a bug report, please remove the below feature
|
||||
request block and provide responses for all of the below items.
|
||||
-->
|
||||
|
||||
**Kibana version**:
|
||||
|
||||
**OS version**:
|
||||
|
||||
**Original install method (e.g. download page, yum, from source, etc.)**:
|
||||
|
||||
**Description of the problem including expected versus actual behavior**:
|
||||
|
||||
**Steps to reproduce**:
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
**Errors in browser console (if relevant)**:
|
||||
|
||||
**Provide logs and/or server output (if relevant)**:
|
||||
|
||||
<!--
|
||||
If you are filing a feature request, please remove the above bug
|
||||
report block and provide responses for all of the below items.
|
||||
-->
|
||||
|
||||
**Describe the feature**:
|
13
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
13
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!--
|
||||
Thank you for your interest in and contributing to Kibana! There
|
||||
are a few simple things to check before submitting your pull request
|
||||
that can help with the review process. You should delete these items
|
||||
from your submission, but they are here to help bring them to your
|
||||
attention.
|
||||
-->
|
||||
|
||||
- Have you signed the [contributor license agreement](https://www.elastic.co/contributor-agreement)?
|
||||
- Have you followed the [contributor guidelines](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md)?
|
||||
- If submitting code, have you included unit tests that cover the changes?
|
||||
- If submitting code, have you tested and built your code locally prior to submission with `npm test && npm run build`?
|
||||
- If submitting code, is your pull request against master? Unless there is a good reason otherwise, we prefer pull requests against master and will backport as needed.
|
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -12,7 +12,10 @@ target
|
|||
.idea
|
||||
*.iml
|
||||
*.log
|
||||
/test/output
|
||||
/test/screenshots/diff
|
||||
/test/screenshots/failure
|
||||
/test/screenshots/session
|
||||
/test/screenshots/visual_regression_gallery.html
|
||||
/esvm
|
||||
.htpasswd
|
||||
.eslintcache
|
||||
|
|
|
@ -113,7 +113,7 @@ Once that is complete just run:
|
|||
|
||||
```
|
||||
sh
|
||||
npm run test && npm run build
|
||||
npm run test && npm run build -- --skip-os-packages
|
||||
```
|
||||
|
||||
#### Debugging unit tests
|
||||
|
@ -121,27 +121,27 @@ npm run test && npm run build
|
|||
The standard `npm run test` task runs several sub tasks and can take several minutes to complete, making debugging failures pretty painful. In order to ease the pain specialized tasks provide alternate methods for running the tests.
|
||||
|
||||
|
||||
`npm run test:quick`
|
||||
`npm run test:quick`
|
||||
Runs both server and browser tests, but skips linting
|
||||
|
||||
`npm run test:server`
|
||||
`npm run test:server`
|
||||
Run only the server tests
|
||||
|
||||
`npm run test:browser`
|
||||
`npm run test:browser`
|
||||
Run only the browser tests. Coverage reports are available for browser tests by running `npm run test:coverage`. You can find the results under the `coverage/` directory that will be created upon completion.
|
||||
|
||||
`npm run test:dev`
|
||||
Initializes an environment for debugging the browser tests. Includes an dedicated instance of the kibana server for building the test bundle, and a karma server. When running this task the build is optimized for the first time and then a karma-owned instance of the browser is opened. Click the "debug" button to open a new tab that executes the unit tests.
|
||||
`npm run test:dev`
|
||||
Initializes an environment for debugging the browser tests. Includes an dedicated instance of the kibana server for building the test bundle, and a karma server. When running this task the build is optimized for the first time and then a karma-owned instance of the browser is opened. Click the "debug" button to open a new tab that executes the unit tests.
|
||||

|
||||
|
||||
`npm run mocha [test file or dir]` or `npm run mocha:debug [test file or dir]`
|
||||
`npm run mocha [test file or dir]` or `npm run mocha:debug [test file or dir]`
|
||||
Run a one off test with the local project version of mocha, babel compilation, and optional debugging. Great
|
||||
for development and fixing individual tests.
|
||||
|
||||
#### Unit testing plugins
|
||||
This should work super if you're using the [Kibana plugin generator](https://github.com/elastic/generator-kibana-plugin). If you're not using the generator, well, you're on your own. We suggest you look at how the generator works.
|
||||
|
||||
`npm run test:dev -- --kbnServer.testsBundle.pluginId=some_special_plugin --kbnServer.plugin-path=../some_special_plugin`
|
||||
`npm run test:dev -- --kbnServer.testsBundle.pluginId=some_special_plugin --kbnServer.plugin-path=../some_special_plugin`
|
||||
Run the tests for just your particular plugin. Assuming you plugin lives outside of the `installedPlugins directory`, which it should.
|
||||
|
||||
#### Running browser automation tests:
|
||||
|
@ -151,13 +151,13 @@ Run the tests for just your particular plugin. Assuming you plugin lives outside
|
|||
|
||||
The following will start Kibana, Elasticsearch and Selenium for you. To run the functional UI tests use the following commands
|
||||
|
||||
`npm run test:ui`
|
||||
`npm run test:ui`
|
||||
Run the functional UI tests one time and exit. This is used by the CI systems and is great for quickly checking that things pass. It is essentially a combination of the next two tasks.
|
||||
|
||||
`npm run test:ui:server`
|
||||
`npm run test:ui:server`
|
||||
Start the server required for the `test:ui:runner` tasks. Once the server is started `test:ui:runner` can be run multiple times without waiting for the server to start.
|
||||
|
||||
`npm run test:ui:runner`
|
||||
`npm run test:ui:runner`
|
||||
Execute the front-end selenium tests. This requires the server started by the `test:ui:server` task.
|
||||
|
||||
##### If you already have ElasticSearch, Kibana, and Selenium Server running:
|
||||
|
@ -184,15 +184,15 @@ npm run test:ui:runner
|
|||
|
||||
Packages are built using fpm, pleaserun, dpkg, and rpm. fpm and pleaserun can be installed using gem. Package building has only been tested on Linux and is not supported on any other platform.
|
||||
```sh
|
||||
gem install pleaserun
|
||||
apt-get install ruby-dev
|
||||
gem install fpm
|
||||
npm run build:ospackages
|
||||
apt-get install ruby-dev rpm
|
||||
gem install fpm -v 1.5.0 # required by pleaserun 0.0.16
|
||||
gem install pleaserun -v 0.0.16 # higher versions fail at the moment
|
||||
npm run build -- --skip-archives
|
||||
```
|
||||
|
||||
To specify a package to build you can add `rpm` or `deb` as an argument.
|
||||
```sh
|
||||
npm run build:ospackages -- --rpm
|
||||
npm run build -- --rpm
|
||||
```
|
||||
|
||||
Distributable packages can be found in `target/` after the build completes.
|
||||
|
|
|
@ -9,7 +9,7 @@ module.exports = function (grunt) {
|
|||
pkg: grunt.file.readJSON('package.json'),
|
||||
root: __dirname,
|
||||
src: __dirname + '/src',
|
||||
build: __dirname + '/build', // temporary build directory
|
||||
buildDir: __dirname + '/build', // temporary build directory
|
||||
plugins: __dirname + '/src/plugins',
|
||||
server: __dirname + '/src/server',
|
||||
target: __dirname + '/target', // location of the compressed build targets
|
||||
|
@ -69,7 +69,10 @@ module.exports = function (grunt) {
|
|||
|
||||
grunt.config.merge(config);
|
||||
|
||||
config.userScriptsDir = __dirname + '/build/userScripts';
|
||||
// must run before even services/platforms
|
||||
grunt.config.set('build', require('./tasks/config/build')(grunt));
|
||||
|
||||
config.packageScriptsDir = __dirname + '/tasks/build/package_scripts';
|
||||
// ensure that these run first, other configs need them
|
||||
config.services = require('./tasks/config/services')(grunt);
|
||||
config.platforms = require('./tasks/config/platforms')(grunt);
|
||||
|
|
14
README.md
14
README.md
|
@ -1,4 +1,4 @@
|
|||
# Kibana 5.0.0-snapshot
|
||||
# Kibana 5.0.0
|
||||
|
||||
Kibana is an open source ([Apache Licensed](https://github.com/elastic/kibana/blob/master/LICENSE.md)), browser based analytics and search dashboard for Elasticsearch. Kibana is a snap to setup and start using. Kibana strives to be easy to get started with, while also being flexible and powerful, just like Elasticsearch.
|
||||
|
||||
|
@ -41,9 +41,9 @@ Visit [Elastic.co](http://www.elastic.co/guide/en/kibana/current/index.html) for
|
|||
|
||||
For the daring, snapshot builds are available. These builds are created after each commit to the master branch, and therefore are not something you should run in production.
|
||||
|
||||
| platform | | | | |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| OSX | [tar](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-darwin-x64.tar.gz) | [zip](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-darwin-x64.zip) | | |
|
||||
| Linux x64 | [tar](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-linux-x64.tar.gz) | [zip](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-linux-x64.zip) | [deb](https://download.elastic.co/kibana/kibana-snapshot/kibana_5.0.0-snapshot_amd64.deb)| [rpm](https://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0_snapshot-1.x86_64.rpm) |
|
||||
| Linux x86 | [tar](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-linux-x86.tar.gz) | [zip](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-linux-x86.zip) | [deb](https://download.elastic.co/kibana/kibana-snapshot/kibana_5.0.0-snapshot_i386.deb) | [rpm](https://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0_snapshot-1.i386.rpm) |
|
||||
| Windows | [tar](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-windows.tar.gz) | [zip](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-windows.zip) | | |
|
||||
| platform | |
|
||||
| --- | --- |
|
||||
| OSX | [tar](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-SNAPSHOT-darwin-x64.tar.gz) |
|
||||
| Linux x64 | [tar](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-SNAPSHOT-linux-x64.tar.gz) [deb](https://download.elastic.co/kibana/kibana-snapshot/kibana_5.0.0-SNAPSHOT_amd64.deb) [rpm](https://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0_SNAPSHOT-1.x86_64.rpm) |
|
||||
| Linux x86 | [tar](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-SNAPSHOT-linux-x86.tar.gz) [deb](https://download.elastic.co/kibana/kibana-snapshot/kibana_5.0.0-SNAPSHOT_i386.deb) [rpm](https://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0_SNAPSHOT-1.i386.rpm) |
|
||||
| Windows | [zip](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-SNAPSHOT-windows.zip) |
|
||||
|
|
822
STYLEGUIDE.md
822
STYLEGUIDE.md
|
@ -1,767 +1,9 @@
|
|||
This is a collection of style guides for Kibana projects. The include guides for the following:
|
||||
|
||||
- [JavaScript](#javascript-style-guide)
|
||||
- [Kibana Project](#kibana-style-guide)
|
||||
- [Html](#html-style-guide)
|
||||
|
||||
# JavaScript Style Guide
|
||||
|
||||
## 2 Spaces for indention
|
||||
|
||||
Use 2 spaces for indenting your code and swear an oath to never mix tabs and
|
||||
spaces - a special kind of hell is awaiting you otherwise.
|
||||
|
||||
## Newlines
|
||||
|
||||
Use UNIX-style newlines (`\n`), and a newline character as the last character
|
||||
of a file. Windows-style newlines (`\r\n`) are forbidden inside any repository.
|
||||
|
||||
## No trailing whitespace
|
||||
|
||||
Just like you brush your teeth after every meal, you clean up any trailing
|
||||
whitespace in your JS files before committing. Otherwise the rotten smell of
|
||||
careless neglect will eventually drive away contributors and/or co-workers.
|
||||
|
||||
## Use Semicolons
|
||||
|
||||
According to [scientific research][hnsemicolons], the usage of semicolons is
|
||||
a core value of our community. Consider the points of [the opposition][], but
|
||||
be a traditionalist when it comes to abusing error correction mechanisms for
|
||||
cheap syntactic pleasures.
|
||||
|
||||
[the opposition]: http://blog.izs.me/post/2353458699/an-open-letter-to-javascript-leaders-regarding
|
||||
[hnsemicolons]: http://news.ycombinator.com/item?id=1547647
|
||||
|
||||
## 120 characters per line
|
||||
|
||||
Try to limit your lines to 80 characters. If it feels right, you can go up to 120 characters.
|
||||
|
||||
## Use single quotes
|
||||
|
||||
Use single quotes, unless you are writing JSON.
|
||||
|
||||
*Right:*
|
||||
|
||||
```js
|
||||
var foo = 'bar';
|
||||
```
|
||||
|
||||
*Wrong:*
|
||||
|
||||
```js
|
||||
var foo = "bar";
|
||||
```
|
||||
|
||||
## Opening braces go on the same line
|
||||
|
||||
Your opening braces go on the same line as the statement.
|
||||
|
||||
*Right:*
|
||||
|
||||
```js
|
||||
if (true) {
|
||||
console.log('winning');
|
||||
}
|
||||
```
|
||||
|
||||
*Wrong:*
|
||||
|
||||
```js
|
||||
if (true)
|
||||
{
|
||||
console.log('losing');
|
||||
}
|
||||
```
|
||||
|
||||
Also, notice the use of whitespace before and after the condition statement.
|
||||
|
||||
## Always use braces for multi-line code
|
||||
|
||||
*Right:*
|
||||
|
||||
```js
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
```
|
||||
|
||||
*Wrong:*
|
||||
|
||||
```js
|
||||
if (err)
|
||||
return cb(err);
|
||||
```
|
||||
|
||||
## Prefer multi-line conditionals
|
||||
|
||||
But single-line conditionals are allowed for short lines
|
||||
|
||||
*Preferred:*
|
||||
|
||||
```js
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
```
|
||||
|
||||
*Allowed:*
|
||||
|
||||
```js
|
||||
if (err) return cb(err);
|
||||
```
|
||||
|
||||
## Declare one variable per var statement
|
||||
|
||||
Declare one variable per var statement, it makes it easier to re-order the
|
||||
lines. However, ignore [Crockford][crockfordconvention] when it comes to
|
||||
declaring variables deeper inside a function, just put the declarations wherever
|
||||
they make sense.
|
||||
|
||||
*Right:*
|
||||
|
||||
```js
|
||||
var keys = ['foo', 'bar'];
|
||||
var values = [23, 42];
|
||||
|
||||
var object = {};
|
||||
while (keys.length) {
|
||||
var key = keys.pop();
|
||||
object[key] = values.pop();
|
||||
}
|
||||
```
|
||||
|
||||
*Wrong:*
|
||||
|
||||
```js
|
||||
var keys = ['foo', 'bar'],
|
||||
values = [23, 42],
|
||||
object = {},
|
||||
key;
|
||||
|
||||
while (keys.length) {
|
||||
key = keys.pop();
|
||||
object[key] = values.pop();
|
||||
}
|
||||
```
|
||||
|
||||
[crockfordconvention]: http://javascript.crockford.com/code.html
|
||||
|
||||
## Use lowerCamelCase for variables, properties and function names
|
||||
|
||||
Variables, properties and function names should use `lowerCamelCase`. They
|
||||
should also be descriptive. Single character variables and uncommon
|
||||
abbreviations should generally be avoided.
|
||||
|
||||
*Right:*
|
||||
|
||||
```js
|
||||
var adminUser = db.query('SELECT * FROM users ...');
|
||||
```
|
||||
|
||||
*Wrong:*
|
||||
|
||||
```js
|
||||
var admin_user = db.query('SELECT * FROM users ...');
|
||||
```
|
||||
|
||||
## Use UpperCamelCase for class names
|
||||
|
||||
Class names should be capitalized using `UpperCamelCase`.
|
||||
|
||||
*Right:*
|
||||
|
||||
```js
|
||||
function BankAccount() {
|
||||
}
|
||||
```
|
||||
|
||||
*Wrong:*
|
||||
|
||||
```js
|
||||
function bank_Account() {
|
||||
}
|
||||
```
|
||||
|
||||
## Use UPPERCASE for Constants
|
||||
|
||||
Constants should be declared as regular variables or static class properties,
|
||||
using all uppercase letters.
|
||||
|
||||
Node.js / V8 actually supports mozilla's [const][const] extension, but
|
||||
unfortunately that cannot be applied to class members, nor is it part of any
|
||||
ECMA standard.
|
||||
|
||||
*Right:*
|
||||
|
||||
```js
|
||||
var SECOND = 1 * 1000;
|
||||
|
||||
function File() {
|
||||
}
|
||||
File.FULL_PERMISSIONS = 0777;
|
||||
```
|
||||
|
||||
*Wrong:*
|
||||
|
||||
```js
|
||||
const SECOND = 1 * 1000;
|
||||
|
||||
function File() {
|
||||
}
|
||||
File.fullPermissions = 0777;
|
||||
```
|
||||
|
||||
[const]: https://developer.mozilla.org/en/JavaScript/Reference/Statements/const
|
||||
|
||||
## Magic numbers
|
||||
|
||||
These are numbers (or other values) simply used in line in your code. **Do not use these**, give them a variable name so they can be understood and changed easily.
|
||||
|
||||
*Right:*
|
||||
|
||||
```js
|
||||
var minWidth = 300;
|
||||
|
||||
if (width < minWidth) {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
*Wrong:*
|
||||
|
||||
```js
|
||||
if (width < 300) {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
## Global definitions
|
||||
|
||||
Don't do this. Everything should be wrapped in a module that can be depended on by other modules. Even things as simple as a single value should be a module.
|
||||
|
||||
## Function definitions
|
||||
|
||||
Prefer the use of function declarations over function expressions. Function expressions are allowed, but should usually be avoided.
|
||||
|
||||
Also, keep function definitions above other code instead of relying on function hoisting.
|
||||
|
||||
*Preferred:*
|
||||
|
||||
```js
|
||||
function myFunc() {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
*Allowed:*
|
||||
|
||||
```js
|
||||
var myFunc = function () {
|
||||
...
|
||||
};
|
||||
```
|
||||
|
||||
## Object / Array creation
|
||||
|
||||
Use trailing commas and put *short* declarations on a single line. Only quote
|
||||
keys when your interpreter complains:
|
||||
|
||||
*Right:*
|
||||
|
||||
```js
|
||||
var a = ['hello', 'world'];
|
||||
var b = {
|
||||
good: 'code',
|
||||
'is generally': 'pretty'
|
||||
};
|
||||
```
|
||||
|
||||
*Wrong:*
|
||||
|
||||
```js
|
||||
var a = [
|
||||
'hello', 'world'
|
||||
];
|
||||
var b = {"good": 'code'
|
||||
, is generally: 'pretty'
|
||||
};
|
||||
```
|
||||
|
||||
## Object / Array iterations, transformations and operations
|
||||
|
||||
Use native ES5 methods to iterate and transform arrays and objects where possible. Do not use `for` and `while` loops.
|
||||
|
||||
Use descriptive variable names in the closures.
|
||||
|
||||
Use a utility library as needed and where it will make code more comprehensible.
|
||||
|
||||
*Right:*
|
||||
|
||||
```js
|
||||
var userNames = users.map(function (user) {
|
||||
return user.name;
|
||||
});
|
||||
|
||||
// examples where lodash makes the code more readable
|
||||
var userNames = _.pluck(users, 'name');
|
||||
```
|
||||
|
||||
*Wrong:*
|
||||
|
||||
```js
|
||||
var userNames = [];
|
||||
for (var i = 0; i < users.length; i++) {
|
||||
userNames.push(users[i].name);
|
||||
}
|
||||
```
|
||||
|
||||
## Use the === operator
|
||||
|
||||
Programming is not about remembering [stupid rules][comparisonoperators]. Use
|
||||
the triple equality operator as it will work just as expected.
|
||||
|
||||
*Right:*
|
||||
|
||||
```js
|
||||
var a = 0;
|
||||
if (a !== '') {
|
||||
console.log('winning');
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
*Wrong:*
|
||||
|
||||
```js
|
||||
var a = 0;
|
||||
if (a == '') {
|
||||
console.log('losing');
|
||||
}
|
||||
```
|
||||
|
||||
[comparisonoperators]: https://developer.mozilla.org/en/JavaScript/Reference/Operators/Comparison_Operators
|
||||
|
||||
## Only use ternary operators for small, simple code
|
||||
|
||||
And **never** use multiple ternaries together
|
||||
|
||||
*Right:*
|
||||
|
||||
```js
|
||||
var foo = (a === b) ? 1 : 2;
|
||||
```
|
||||
|
||||
*Wrong:*
|
||||
|
||||
```js
|
||||
var foo = (a === b) ? 1 : (a === c) ? 2 : 3;
|
||||
```
|
||||
|
||||
## Do not extend built-in prototypes
|
||||
|
||||
Do not extend the prototype of native JavaScript objects. Your future self will
|
||||
be forever grateful.
|
||||
|
||||
*Right:*
|
||||
|
||||
```js
|
||||
var a = [];
|
||||
if (!a.length) {
|
||||
console.log('winning');
|
||||
}
|
||||
```
|
||||
|
||||
*Wrong:*
|
||||
|
||||
```js
|
||||
Array.prototype.empty = function() {
|
||||
return !this.length;
|
||||
}
|
||||
|
||||
var a = [];
|
||||
if (a.empty()) {
|
||||
console.log('losing');
|
||||
}
|
||||
```
|
||||
|
||||
## Use descriptive conditions
|
||||
|
||||
Any non-trivial conditions should be assigned to a descriptively named variables, broken into
|
||||
several names variables, or converted to be a function:
|
||||
|
||||
*Right:*
|
||||
|
||||
```js
|
||||
var thing = ...;
|
||||
var isShape = thing instanceof Shape;
|
||||
var notSquare = !(thing instanceof Square);
|
||||
var largerThan10 = isShape && thing.size > 10;
|
||||
|
||||
if (isShape && notSquare && largerThan10) {
|
||||
console.log('some big polygon');
|
||||
}
|
||||
```
|
||||
|
||||
*Wrong:*
|
||||
|
||||
```js
|
||||
if (
|
||||
thing instanceof Shape
|
||||
&& !(thing instanceof Square)
|
||||
&& thing.size > 10
|
||||
) {
|
||||
console.log('bigger than ten?? Woah!');
|
||||
}
|
||||
```
|
||||
|
||||
## Name regular expressions
|
||||
|
||||
*Right:*
|
||||
|
||||
```js
|
||||
var validPasswordRE = /^(?=.*\d).{4,}$/;
|
||||
|
||||
if (password.length >= 4 && validPasswordRE.test(password)) {
|
||||
console.log('password is valid');
|
||||
}
|
||||
```
|
||||
|
||||
*Wrong:*
|
||||
|
||||
```js
|
||||
if (password.length >= 4 && /^(?=.*\d).{4,}$/.test(password)) {
|
||||
console.log('losing');
|
||||
}
|
||||
```
|
||||
|
||||
## Write small functions
|
||||
|
||||
Keep your functions short. A good function fits on a slide that the people in
|
||||
the last row of a big room can comfortably read. So don't count on them having
|
||||
perfect vision and limit yourself to ~15 lines of code per function.
|
||||
|
||||
## Return early from functions
|
||||
|
||||
To avoid deep nesting of if-statements, always return a function's value as early
|
||||
as possible.
|
||||
|
||||
*Right:*
|
||||
|
||||
```js
|
||||
function isPercentage(val) {
|
||||
if (val < 0) return false;
|
||||
if (val > 100) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
*Wrong:*
|
||||
|
||||
```js
|
||||
function isPercentage(val) {
|
||||
if (val >= 0) {
|
||||
if (val < 100) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Or for this particular example it may also be fine to shorten things even
|
||||
further:
|
||||
|
||||
```js
|
||||
function isPercentage(val) {
|
||||
var isInRange = (val >= 0 && val <= 100);
|
||||
return isInRange;
|
||||
}
|
||||
```
|
||||
|
||||
## Chaining operations
|
||||
|
||||
When using a chaining syntax (jquery or promises, for example), do not indent the subsequent chained operations, unless there is a logical grouping in them.
|
||||
|
||||
Also, if the chain is long, each method should be on a new line.
|
||||
|
||||
*Right:*
|
||||
|
||||
```js
|
||||
$('.someClass')
|
||||
.addClass('another-class')
|
||||
.append(someElement)
|
||||
```
|
||||
|
||||
```js
|
||||
d3.selectAll('g.bar')
|
||||
.enter()
|
||||
.append('thing')
|
||||
.data(anything)
|
||||
.exit()
|
||||
.each(function() ... )
|
||||
```
|
||||
|
||||
```js
|
||||
$http.get('/info')
|
||||
.then(({ data }) => this.transfromInfo(data))
|
||||
.then((transformed) => $http.post('/new-info', transformed))
|
||||
.then(({ data }) => console.log(data));
|
||||
```
|
||||
|
||||
*Wrong:*
|
||||
|
||||
```js
|
||||
$('.someClass')
|
||||
.addClass('another-class')
|
||||
.append(someElement)
|
||||
```
|
||||
|
||||
```js
|
||||
d3.selectAll('g.bar')
|
||||
.enter().append('thing').data(anything).exit()
|
||||
.each(function() ... )
|
||||
```
|
||||
|
||||
```js
|
||||
$http.get('/info')
|
||||
.then(({ data }) => this.transfromInfo(data))
|
||||
.then((transformed) => $http.post('/new-info', transformed))
|
||||
.then(({ data }) => console.log(data));
|
||||
```
|
||||
|
||||
## Name your closures
|
||||
|
||||
Feel free to give your closures a descriptive name. It shows that you care about them, and
|
||||
will produce better stack traces, heap and cpu profiles.
|
||||
|
||||
*Right:*
|
||||
|
||||
```js
|
||||
req.on('end', function onEnd() {
|
||||
console.log('winning');
|
||||
});
|
||||
```
|
||||
|
||||
*Wrong:*
|
||||
|
||||
```js
|
||||
req.on('end', function() {
|
||||
console.log('losing');
|
||||
});
|
||||
```
|
||||
|
||||
## No nested closures
|
||||
|
||||
Use closures, but don't nest them. Otherwise your code will become a mess.
|
||||
|
||||
*Right:*
|
||||
|
||||
```js
|
||||
setTimeout(function() {
|
||||
client.connect(afterConnect);
|
||||
}, 1000);
|
||||
|
||||
function afterConnect() {
|
||||
console.log('winning');
|
||||
}
|
||||
```
|
||||
|
||||
*Wrong:*
|
||||
|
||||
```js
|
||||
setTimeout(function() {
|
||||
client.connect(function() {
|
||||
console.log('losing');
|
||||
});
|
||||
}, 1000);
|
||||
```
|
||||
|
||||
## Use slashes for comments
|
||||
|
||||
Use slashes for both single line and multi line comments. Try to write
|
||||
comments that explain higher level mechanisms or clarify difficult
|
||||
segments of your code. **Don't use comments to restate trivial things**.
|
||||
|
||||
***Exception:*** Comment blocks describing a function and its arguments (docblock) should start with `/**`, contain a single `*` at the beginning of each line, and end with `*/`.
|
||||
|
||||
*Right:*
|
||||
|
||||
```js
|
||||
// 'ID_SOMETHING=VALUE' -> ['ID_SOMETHING=VALUE', 'SOMETHING', 'VALUE']
|
||||
var matches = item.match(/ID_([^\n]+)=([^\n]+)/));
|
||||
|
||||
/**
|
||||
* Fetches a user from...
|
||||
* @param {string} id - id of the user
|
||||
* @return {Promise}
|
||||
*/
|
||||
function loadUser(id) {
|
||||
// This function has a nasty side effect where a failure to increment a
|
||||
// redis counter used for statistics will cause an exception. This needs
|
||||
// to be fixed in a later iteration.
|
||||
|
||||
...
|
||||
}
|
||||
|
||||
var isSessionValid = (session.expires < Date.now());
|
||||
if (isSessionValid) {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
*Wrong:*
|
||||
|
||||
```js
|
||||
// Execute a regex
|
||||
var matches = item.match(/ID_([^\n]+)=([^\n]+)/));
|
||||
|
||||
// Usage: loadUser(5, function() { ... })
|
||||
function loadUser(id, cb) {
|
||||
// ...
|
||||
}
|
||||
|
||||
// Check if the session is valid
|
||||
var isSessionValid = (session.expires < Date.now());
|
||||
// If the session is valid
|
||||
if (isSessionValid) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
## Do not comment out code
|
||||
|
||||
We use a version management system. If a line of code is no longer needed, remove it, don't simply comment it out.
|
||||
|
||||
## Classes/Constructors and Inheritance
|
||||
|
||||
While JavaScript it is not always considered an object-oriented language, it does have the building blocks for writing object oriented code. Of course, as with all things JavaScript, there are many ways this can be accomplished. Generally, we try to err on the side of readability.
|
||||
|
||||
### Capitalized function definition as Constructors
|
||||
|
||||
When Defining a Class/Constructor, use the function definition syntax.
|
||||
|
||||
*Right:*
|
||||
```js
|
||||
function ClassName() {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
*Wrong:*
|
||||
```js
|
||||
var ClassName = function () {};
|
||||
```
|
||||
|
||||
### Inheritance should be done with a utility
|
||||
|
||||
While you can do it with pure JS, a utility will remove a lot of boilerplate, and be more readable and functional.
|
||||
|
||||
*Right:*
|
||||
|
||||
```js
|
||||
// uses a lodash inherits mixin
|
||||
// inheritance is defined first - it's easier to read and the function will be hoisted
|
||||
_.class(Square).inherits(Shape);
|
||||
|
||||
function Square(width, height) {
|
||||
Square.Super.call(this);
|
||||
}
|
||||
```
|
||||
|
||||
*Wrong:*
|
||||
|
||||
```js
|
||||
function Square(width, height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
Square.prototype = Object.create(Shape);
|
||||
```
|
||||
|
||||
### Keep Constructors Small
|
||||
|
||||
It is often the case that there are properties that can't be defined on the prototype, or work that needs to be done to completely create an object (like call its Super class). This is all that should be done within constructors.
|
||||
|
||||
Try to follow the [Write small functions](#write-small-functions) rule here too.
|
||||
|
||||
### Use the prototype
|
||||
|
||||
If a method/property *can* go on the prototype, it probably should.
|
||||
|
||||
```js
|
||||
function Square() {
|
||||
...
|
||||
}
|
||||
|
||||
/**
|
||||
* method does stuff
|
||||
* @return {undefined}
|
||||
*/
|
||||
Square.prototype.method = function () {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### Handling scope and aliasing `this`
|
||||
|
||||
When creating a prototyped class, each method should almost always start with:
|
||||
|
||||
`var self = this;`
|
||||
|
||||
With the exception of very short methods (roughly 3 lines or less), `self` should always be used in place of `this`.
|
||||
|
||||
Avoid the use of `bind`
|
||||
|
||||
*Right:*
|
||||
|
||||
```js
|
||||
Square.prototype.doFancyThings = function () {
|
||||
var self = this;
|
||||
|
||||
somePromiseUtil()
|
||||
.then(function (result) {
|
||||
self.prop = result.prop;
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
*Wrong:*
|
||||
|
||||
```js
|
||||
Square.prototype.doFancyThings = function () {
|
||||
somePromiseUtil()
|
||||
.then(function (result) {
|
||||
this.prop = result.prop;
|
||||
}).bind(this);
|
||||
}
|
||||
```
|
||||
|
||||
*Allowed:*
|
||||
|
||||
```js
|
||||
Square.prototype.area = function () {
|
||||
return this.width * this.height;
|
||||
}
|
||||
```
|
||||
|
||||
## Object.freeze, Object.preventExtensions, Object.seal, with, eval
|
||||
|
||||
Crazy shit that you will probably never need. Stay away from it.
|
||||
|
||||
## Getters and Setters
|
||||
|
||||
Feel free to use getters that are free from [side effects][sideeffect], like
|
||||
providing a length property for a collection class.
|
||||
|
||||
Do not use setters, they cause more problems for people who try to use your
|
||||
software than they can solve.
|
||||
|
||||
[sideeffect]: http://en.wikipedia.org/wiki/Side_effect_(computer_science)
|
||||
- [JavaScript](style_guides/js_style_guide.md)
|
||||
- [CSS](style_guides/css_style_guide.md)
|
||||
- [HTML](style_guides/html_style_guide.md)
|
||||
- [API](style_guides/api_style_guide.md)
|
||||
|
||||
# Kibana Style Guide
|
||||
|
||||
|
@ -866,59 +108,3 @@ require('ui/routes')
|
|||
// angular route code goes here
|
||||
});
|
||||
```
|
||||
|
||||
# Html Style Guide
|
||||
|
||||
## Multiple attribute values
|
||||
|
||||
When a node has multiple attributes that would cause it to exceed the line character limit, each attribute including the first should be on its own line with a single indent. Also, when a node that is styled in this way has child nodes, there should be a blank line between the opening parent tag and the first child tag.
|
||||
|
||||
```
|
||||
<ul
|
||||
attribute1="value1"
|
||||
attribute2="value2"
|
||||
attribute3="value3">
|
||||
|
||||
<li></li>
|
||||
<li></li>
|
||||
...
|
||||
</ul>
|
||||
```
|
||||
|
||||
# Api Style Guide
|
||||
|
||||
## Paths
|
||||
|
||||
API routes must start with the `/api/` path segment, and should be followed by the plugin id if applicable:
|
||||
|
||||
*Right:* `/api/marvel/v1/nodes`
|
||||
*Wrong:* `/marvel/api/v1/nodes`
|
||||
|
||||
## Versions
|
||||
|
||||
Kibana won't be supporting multiple API versions, so API's should not define a version.
|
||||
|
||||
*Right:* `/api/kibana/index_patterns`
|
||||
*Wrong:* `/api/kibana/v1/index_patterns`
|
||||
|
||||
## snake_case
|
||||
|
||||
Kibana uses `snake_case` for the entire API, just like Elasticsearch. All urls, paths, query string parameters, values, and bodies should be `snake_case` formatted.
|
||||
|
||||
*Right:*
|
||||
```
|
||||
POST /api/kibana/index_patterns
|
||||
{
|
||||
"id": "...",
|
||||
"time_field_name": "...",
|
||||
"fields": [
|
||||
...
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
# Attribution
|
||||
|
||||
This JavaScript guide forked from the [node style guide](https://github.com/felixge/node-style-guide) created by [Felix Geisendörfer](http://felixge.de/) and is
|
||||
licensed under the [CC BY-SA 3.0](http://creativecommons.org/licenses/by-sa/3.0/)
|
||||
license.
|
||||
|
|
|
@ -88,5 +88,5 @@
|
|||
# logging.verbose: false
|
||||
|
||||
# Set the interval in milliseconds to sample system and process performance
|
||||
# metrics. Minimum is 100ms. Defaults to 10000.
|
||||
# ops.interval: 10000
|
||||
# metrics. Minimum is 100ms. Defaults to 5000.
|
||||
# ops.interval: 5000
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
:k4pull: https://github.com/elastic/kibana/pull/
|
||||
:version: master
|
||||
:esversion: master
|
||||
:packageversion: master
|
||||
|
||||
include::introduction.asciidoc[]
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ wget -qO - https://packages.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add
|
|||
+
|
||||
["source","sh",subs="attributes"]
|
||||
--------------------------------------------------
|
||||
echo "deb http://packages.elastic.co/kibana/{version}/debian stable main" | sudo tee -a /etc/apt/sources.list.d/kibana.list
|
||||
echo "deb https://packages.elastic.co/kibana/{packageversion}/debian stable main" | sudo tee -a /etc/apt/sources.list.d/kibana.list
|
||||
--------------------------------------------------
|
||||
+
|
||||
[WARNING]
|
||||
|
@ -82,11 +82,11 @@ rpm --import https://packages.elastic.co/GPG-KEY-elasticsearch
|
|||
+
|
||||
["source","sh",subs="attributes"]
|
||||
--------------------------------------------------
|
||||
[kibana-{version}]
|
||||
name=Kibana repository for {version}.x packages
|
||||
baseurl=http://packages.elastic.co/kibana/{version}/centos
|
||||
[kibana-{packageversion}]
|
||||
name=Kibana repository for {packageversion} packages
|
||||
baseurl=https://packages.elastic.co/kibana/{packageversion}/centos
|
||||
gpgcheck=1
|
||||
gpgkey=http://packages.elastic.co/GPG-KEY-elasticsearch
|
||||
gpgkey=https://packages.elastic.co/GPG-KEY-elasticsearch
|
||||
enabled=1
|
||||
--------------------------------------------------
|
||||
+
|
||||
|
|
|
@ -27,7 +27,7 @@ authority for your Elasticsearch instance.
|
|||
to `false`.
|
||||
`elasticsearch.pingTimeout:`:: *Default: the value of the `elasticsearch.requestTimeout` setting* Time in milliseconds to
|
||||
wait for Elasticsearch to respond to pings.
|
||||
`elasticsearch.requestTimeout:`:: *Default: 300000* Time in milliseconds to wait for responses from the back end or
|
||||
`elasticsearch.requestTimeout:`:: *Default: 30000* Time in milliseconds to wait for responses from the back end or
|
||||
Elasticsearch. This value must be a positive integer.
|
||||
`elasticsearch.requestHeadersWhitelist:`:: *Default: `[ 'authorization' ]`* List of Kibana client-side headers to send to Elasticsearch.
|
||||
To send *no* client-side headers, set this value to [] (an empty list).
|
||||
|
@ -42,7 +42,7 @@ retrying.
|
|||
error messages.
|
||||
`logging.verbose`:: *Default: false* Set the value of this setting to `true` to log all events, including system usage
|
||||
information and all requests.
|
||||
`ops.interval`:: *Default: 10000* Set the interval in milliseconds to sample system and process performance metrics.
|
||||
`ops.interval`:: *Default: 5000* Set the interval in milliseconds to sample system and process performance metrics.
|
||||
The minimum value is 100.
|
||||
`status.allowAnonymous`:: *Default: false* If authentication is enabled, setting this to `true` allows
|
||||
unauthenticated users to access the Kibana server status API and status page.
|
||||
|
|
22
package.json
22
package.json
|
@ -11,7 +11,7 @@
|
|||
"dashboarding"
|
||||
],
|
||||
"private": false,
|
||||
"version": "5.0.0-snapshot",
|
||||
"version": "5.0.0-alpha4",
|
||||
"build": {
|
||||
"number": 8467,
|
||||
"sha": "6cb7fec4e154faa0a4a3fee4b33dfef91b9870d9"
|
||||
|
@ -38,7 +38,7 @@
|
|||
"Tim Sullivan <tim@elastic.co>"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "grunt test",
|
||||
"test": "grunt test; grunt test:visualRegression",
|
||||
"test:dev": "grunt test:dev",
|
||||
"test:quick": "grunt test:quick",
|
||||
"test:browser": "grunt test:browser",
|
||||
|
@ -48,7 +48,6 @@
|
|||
"test:server": "grunt test:server",
|
||||
"test:coverage": "grunt test:coverage",
|
||||
"build": "grunt build",
|
||||
"build:ospackages": "grunt build --os-packages",
|
||||
"start": "sh ./bin/kibana --dev",
|
||||
"precommit": "grunt precommit",
|
||||
"karma": "karma start",
|
||||
|
@ -95,8 +94,10 @@
|
|||
"commander": "2.8.1",
|
||||
"css-loader": "0.17.0",
|
||||
"d3": "3.5.6",
|
||||
"dragula": "3.7.0",
|
||||
"elasticsearch": "10.1.2",
|
||||
"elasticsearch-browser": "10.1.2",
|
||||
"even-better": "7.0.2",
|
||||
"expiry-js": "0.1.7",
|
||||
"exports-loader": "0.6.2",
|
||||
"expose-loader": "0.7.0",
|
||||
|
@ -104,7 +105,6 @@
|
|||
"file-loader": "0.8.4",
|
||||
"font-awesome": "4.4.0",
|
||||
"glob-all": "3.0.1",
|
||||
"good": "6.3.0",
|
||||
"good-squeeze": "2.1.0",
|
||||
"gridster": "0.5.6",
|
||||
"hapi": "8.8.1",
|
||||
|
@ -125,8 +125,8 @@
|
|||
"marked": "0.3.3",
|
||||
"minimatch": "2.0.10",
|
||||
"mkdirp": "0.5.1",
|
||||
"moment": "2.10.6",
|
||||
"moment-timezone": "0.4.1",
|
||||
"moment": "2.13.0",
|
||||
"moment-timezone": "0.5.4",
|
||||
"node-uuid": "1.4.7",
|
||||
"raw-loader": "0.5.1",
|
||||
"request": "2.61.0",
|
||||
|
@ -153,8 +153,11 @@
|
|||
"auto-release-sinon": "1.0.3",
|
||||
"babel-eslint": "4.1.8",
|
||||
"chokidar": "1.4.3",
|
||||
"dot": "1.0.3",
|
||||
"elasticdump": "2.1.1",
|
||||
"eslint": "1.10.3",
|
||||
"eslint-plugin-mocha": "1.1.0",
|
||||
"event-stream": "3.3.2",
|
||||
"expect.js": "0.3.1",
|
||||
"faker": "1.1.0",
|
||||
"grunt": "0.4.5",
|
||||
|
@ -162,7 +165,7 @@
|
|||
"grunt-cli": "0.1.13",
|
||||
"grunt-contrib-clean": "0.6.0",
|
||||
"grunt-contrib-copy": "0.8.1",
|
||||
"grunt-esvm": "3.1.1",
|
||||
"grunt-esvm": "3.2.1",
|
||||
"grunt-karma": "0.12.0",
|
||||
"grunt-run": "0.5.0",
|
||||
"grunt-s3": "0.2.0-alpha.3",
|
||||
|
@ -170,6 +173,7 @@
|
|||
"gruntify-eslint": "1.0.1",
|
||||
"html-entities": "1.1.3",
|
||||
"husky": "0.8.1",
|
||||
"image-diff": "1.6.0",
|
||||
"intern": "3.0.1",
|
||||
"istanbul-instrumenter-loader": "0.1.3",
|
||||
"karma": "0.13.9",
|
||||
|
@ -181,14 +185,14 @@
|
|||
"karma-safari-launcher": "0.1.1",
|
||||
"license-checker": "3.1.0",
|
||||
"load-grunt-config": "0.19.1",
|
||||
"makelogs": "3.0.0-beta3",
|
||||
"makelogs": "3.0.0",
|
||||
"marked-text-renderer": "0.1.0",
|
||||
"mocha": "2.3.0",
|
||||
"ncp": "2.0.0",
|
||||
"nock": "2.10.0",
|
||||
"npm": "2.11.0",
|
||||
"portscanner": "1.0.0",
|
||||
"simple-git": "1.8.0",
|
||||
"simple-git": "1.37.0",
|
||||
"sinon": "1.17.2",
|
||||
"source-map": "0.4.4",
|
||||
"source-map-support": "0.4.0",
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
server:
|
||||
port: 8274
|
||||
logging:
|
||||
json: true
|
||||
optimize:
|
||||
enabled: false
|
90
src/cli/serve/__tests__/reload_logging_config.js
Normal file
90
src/cli/serve/__tests__/reload_logging_config.js
Normal file
|
@ -0,0 +1,90 @@
|
|||
import { spawn } from 'child_process';
|
||||
import { writeFileSync, readFile } from 'fs';
|
||||
import { relative, resolve } from 'path';
|
||||
import { safeDump } from 'js-yaml';
|
||||
import es from 'event-stream';
|
||||
import readYamlConfig from '../read_yaml_config';
|
||||
import expect from 'expect.js';
|
||||
const testConfigFile = follow(`fixtures/reload_logging_config/kibana.test.yml`);
|
||||
const cli = follow(`../../../../bin/kibana`);
|
||||
|
||||
function follow(file) {
|
||||
return relative(process.cwd(), resolve(__dirname, file));
|
||||
}
|
||||
|
||||
function setLoggingJson(enabled) {
|
||||
const conf = readYamlConfig(testConfigFile);
|
||||
conf.logging = conf.logging || {};
|
||||
conf.logging.json = enabled;
|
||||
const yaml = safeDump(conf);
|
||||
writeFileSync(testConfigFile, yaml);
|
||||
return conf;
|
||||
}
|
||||
|
||||
describe(`Server logging configuration`, function () {
|
||||
it(`should be reloadable via SIGHUP process signaling`, function (done) {
|
||||
this.timeout(60000);
|
||||
|
||||
let asserted = false;
|
||||
let json = Infinity;
|
||||
const conf = setLoggingJson(true);
|
||||
const child = spawn(cli, [`--config`, testConfigFile]);
|
||||
|
||||
child.on('error', err => {
|
||||
done(new Error(`error in child process while attempting to reload config.
|
||||
${err.stack || err.message || err}`));
|
||||
});
|
||||
|
||||
child.on('exit', code => {
|
||||
expect(asserted).to.eql(true);
|
||||
expect(code === null || code === 0).to.eql(true);
|
||||
done();
|
||||
});
|
||||
|
||||
child.stdout
|
||||
.pipe(es.split())
|
||||
.pipe(es.mapSync(function (line) {
|
||||
if (!line) {
|
||||
return line; // ignore empty lines
|
||||
}
|
||||
if (json--) {
|
||||
expect(parseJsonLogLine).withArgs(line).to.not.throwError();
|
||||
} else {
|
||||
expectPlainTextLogLine(line);
|
||||
}
|
||||
}));
|
||||
|
||||
function parseJsonLogLine(line) {
|
||||
try {
|
||||
const data = JSON.parse(line);
|
||||
const listening = data.tags.indexOf(`listening`) !== -1;
|
||||
if (listening) {
|
||||
switchToPlainTextLog();
|
||||
}
|
||||
} catch (err) {
|
||||
expect(`Error parsing log line as JSON\n
|
||||
${err.stack || err.message || err}`).to.eql(true);
|
||||
}
|
||||
}
|
||||
|
||||
function switchToPlainTextLog() {
|
||||
json = 3; // ignore both "reloading" messages + ui settings status message
|
||||
setLoggingJson(false);
|
||||
child.kill(`SIGHUP`); // reload logging config
|
||||
}
|
||||
|
||||
function expectPlainTextLogLine(line) {
|
||||
// assert
|
||||
const tags = `[\u001b[32minfo\u001b[39m][\u001b[36mconfig\u001b[39m]`;
|
||||
const status = `Reloaded logging configuration due to SIGHUP.`;
|
||||
const expected = `${tags} ${status}`;
|
||||
const actual = line.slice(-expected.length);
|
||||
expect(actual).to.eql(expected);
|
||||
|
||||
// cleanup
|
||||
asserted = true;
|
||||
setLoggingJson(true);
|
||||
child.kill();
|
||||
}
|
||||
});
|
||||
});
|
|
@ -2,11 +2,8 @@ import _ from 'lodash';
|
|||
import { statSync } from 'fs';
|
||||
import { isWorker } from 'cluster';
|
||||
import { resolve } from 'path';
|
||||
|
||||
import readYamlConfig from './read_yaml_config';
|
||||
import { fromRoot } from '../../utils';
|
||||
|
||||
const cwd = process.cwd();
|
||||
import readYamlConfig from './read_yaml_config';
|
||||
|
||||
let canCluster;
|
||||
try {
|
||||
|
@ -28,7 +25,7 @@ const configPathCollector = pathCollector();
|
|||
const pluginDirCollector = pathCollector();
|
||||
const pluginPathCollector = pathCollector();
|
||||
|
||||
function initServerSettings(opts, extraCliOptions) {
|
||||
function readServerSettings(opts, extraCliOptions) {
|
||||
const settings = readYamlConfig(opts.config);
|
||||
const set = _.partial(_.set, settings);
|
||||
const get = _.partial(_.get, settings);
|
||||
|
@ -128,7 +125,8 @@ module.exports = function (program) {
|
|||
}
|
||||
}
|
||||
|
||||
const settings = initServerSettings(opts, this.getUnknownOptions());
|
||||
const getCurrentSettings = () => readServerSettings(opts, this.getUnknownOptions());
|
||||
const settings = getCurrentSettings();
|
||||
|
||||
if (canCluster && opts.dev && !isWorker) {
|
||||
// stop processing the action and handoff to cluster manager
|
||||
|
@ -156,6 +154,13 @@ module.exports = function (program) {
|
|||
process.exit(1); // eslint-disable-line no-process-exit
|
||||
}
|
||||
|
||||
process.on('SIGHUP', function reloadConfig() {
|
||||
const settings = getCurrentSettings();
|
||||
kbnServer.server.log(['info', 'config'], 'Reloading logging configuration due to SIGHUP.');
|
||||
kbnServer.applyLoggingConfiguration(settings);
|
||||
kbnServer.server.log(['info', 'config'], 'Reloaded logging configuration due to SIGHUP.');
|
||||
});
|
||||
|
||||
return kbnServer;
|
||||
});
|
||||
};
|
||||
|
|
|
@ -44,8 +44,8 @@ describe('kibana cli', function () {
|
|||
workingPath: testWorkingPath,
|
||||
tempArchiveFile: tempArchiveFilePath,
|
||||
plugin: 'test-plugin',
|
||||
version: '5.0.0-snapshot',
|
||||
plugins: [ { name: 'foo', path: join(testWorkingPath, 'foo'), version: '5.0.0-snapshot' } ]
|
||||
version: '5.0.0-SNAPSHOT',
|
||||
plugins: [ { name: 'foo', path: join(testWorkingPath, 'foo'), version: '5.0.0-SNAPSHOT' } ]
|
||||
};
|
||||
const errorStub = sinon.stub();
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import { fromRoot } from '../../utils';
|
||||
import fs from 'fs';
|
||||
import install from './install';
|
||||
import Logger from '../lib/logger';
|
||||
import pkg from '../../utils/package_json';
|
||||
import { parse, parseMilliseconds } from './settings';
|
||||
import { find } from 'lodash';
|
||||
|
||||
function processCommand(command, options) {
|
||||
let settings;
|
||||
|
@ -18,6 +20,24 @@ function processCommand(command, options) {
|
|||
install(settings, logger);
|
||||
}
|
||||
|
||||
function getDefaultConfigPath() {
|
||||
const paths = [
|
||||
fromRoot('config/kibana.yml'),
|
||||
'/etc/kibana/kibana.yml'
|
||||
];
|
||||
|
||||
const availablePath = find(paths, configPath => {
|
||||
try {
|
||||
fs.accessSync(configPath, fs.R_OK);
|
||||
return true;
|
||||
} catch (e) {
|
||||
//Check the next path
|
||||
}
|
||||
});
|
||||
|
||||
return availablePath || paths[0];
|
||||
}
|
||||
|
||||
export default function pluginInstall(program) {
|
||||
program
|
||||
.command('install <plugin/url>')
|
||||
|
@ -26,7 +46,7 @@ export default function pluginInstall(program) {
|
|||
.option(
|
||||
'-c, --config <path>',
|
||||
'path to the config file',
|
||||
fromRoot('config/kibana.yml')
|
||||
getDefaultConfigPath()
|
||||
)
|
||||
.option(
|
||||
'-t, --timeout <duration>',
|
||||
|
|
|
@ -5,7 +5,14 @@ import mkdirp from 'mkdirp';
|
|||
import Logger from '../../lib/logger';
|
||||
import list from '../list';
|
||||
import { join } from 'path';
|
||||
import { writeFileSync } from 'fs';
|
||||
import { writeFileSync, appendFileSync } from 'fs';
|
||||
|
||||
|
||||
function createPlugin(name, version, pluginBaseDir) {
|
||||
const pluginDir = join(pluginBaseDir, name);
|
||||
mkdirp.sync(pluginDir);
|
||||
appendFileSync(join(pluginDir, 'package.json'), '{"version": "' + version + '"}');
|
||||
}
|
||||
|
||||
describe('kibana cli', function () {
|
||||
|
||||
|
@ -33,41 +40,61 @@ describe('kibana cli', function () {
|
|||
});
|
||||
|
||||
it('list all of the folders in the plugin folder', function () {
|
||||
mkdirp.sync(join(pluginDir, 'plugin1'));
|
||||
mkdirp.sync(join(pluginDir, 'plugin2'));
|
||||
mkdirp.sync(join(pluginDir, 'plugin3'));
|
||||
createPlugin('plugin1', '5.0.0-alpha2', pluginDir);
|
||||
createPlugin('plugin2', '3.2.1', pluginDir);
|
||||
createPlugin('plugin3', '1.2.3', pluginDir);
|
||||
|
||||
list(settings, logger);
|
||||
|
||||
expect(logger.log.calledWith('plugin1')).to.be(true);
|
||||
expect(logger.log.calledWith('plugin2')).to.be(true);
|
||||
expect(logger.log.calledWith('plugin3')).to.be(true);
|
||||
expect(logger.log.calledWith('plugin1@5.0.0-alpha2')).to.be(true);
|
||||
expect(logger.log.calledWith('plugin2@3.2.1')).to.be(true);
|
||||
expect(logger.log.calledWith('plugin3@1.2.3')).to.be(true);
|
||||
});
|
||||
|
||||
it('ignore folders that start with a period', function () {
|
||||
mkdirp.sync(join(pluginDir, '.foo'));
|
||||
mkdirp.sync(join(pluginDir, 'plugin1'));
|
||||
mkdirp.sync(join(pluginDir, 'plugin2'));
|
||||
mkdirp.sync(join(pluginDir, 'plugin3'));
|
||||
mkdirp.sync(join(pluginDir, '.bar'));
|
||||
createPlugin('.foo', '1.0.0', pluginDir);
|
||||
createPlugin('plugin1', '5.0.0-alpha2', pluginDir);
|
||||
createPlugin('plugin2', '3.2.1', pluginDir);
|
||||
createPlugin('plugin3', '1.2.3', pluginDir);
|
||||
createPlugin('.bar', '1.0.0', pluginDir);
|
||||
|
||||
list(settings, logger);
|
||||
|
||||
expect(logger.log.calledWith('.foo')).to.be(false);
|
||||
expect(logger.log.calledWith('.bar')).to.be(false);
|
||||
expect(logger.log.calledWith('.foo@1.0.0')).to.be(false);
|
||||
expect(logger.log.calledWith('.bar@1.0.0')).to.be(false);
|
||||
});
|
||||
|
||||
it('list should only list folders', function () {
|
||||
mkdirp.sync(join(pluginDir, 'plugin1'));
|
||||
mkdirp.sync(join(pluginDir, 'plugin2'));
|
||||
mkdirp.sync(join(pluginDir, 'plugin3'));
|
||||
createPlugin('plugin1', '1.0.0', pluginDir);
|
||||
createPlugin('plugin2', '1.0.0', pluginDir);
|
||||
createPlugin('plugin3', '1.0.0', pluginDir);
|
||||
writeFileSync(join(pluginDir, 'plugin4'), 'This is a file, and not a folder.');
|
||||
|
||||
list(settings, logger);
|
||||
|
||||
expect(logger.log.calledWith('plugin1')).to.be(true);
|
||||
expect(logger.log.calledWith('plugin2')).to.be(true);
|
||||
expect(logger.log.calledWith('plugin3')).to.be(true);
|
||||
expect(logger.log.calledWith('plugin1@1.0.0')).to.be(true);
|
||||
expect(logger.log.calledWith('plugin2@1.0.0')).to.be(true);
|
||||
expect(logger.log.calledWith('plugin3@1.0.0')).to.be(true);
|
||||
});
|
||||
|
||||
it('list should throw an exception if a plugin does not have a package.json', function () {
|
||||
createPlugin('plugin1', '1.0.0', pluginDir);
|
||||
mkdirp.sync(join(pluginDir, 'empty-plugin'));
|
||||
|
||||
expect(function () {
|
||||
list(settings, logger);
|
||||
}).to.throwError('Unable to read package.json file for plugin empty-plugin');
|
||||
});
|
||||
|
||||
it('list should throw an exception if a plugin have an empty package.json', function () {
|
||||
createPlugin('plugin1', '1.0.0', pluginDir);
|
||||
const invalidPluginDir = join(pluginDir, 'invalid-plugin');
|
||||
mkdirp.sync(invalidPluginDir);
|
||||
appendFileSync(join(invalidPluginDir, 'package.json'), '');
|
||||
|
||||
expect(function () {
|
||||
list(settings, logger);
|
||||
}).to.throwError('Unable to read package.json file for plugin invalid-plugin');
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { statSync, readdirSync } from 'fs';
|
||||
import { statSync, readdirSync, readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
export default function list(settings, logger) {
|
||||
|
@ -7,7 +7,13 @@ export default function list(settings, logger) {
|
|||
const stat = statSync(join(settings.pluginDir, filename));
|
||||
|
||||
if (stat.isDirectory() && filename[0] !== '.') {
|
||||
logger.log(filename);
|
||||
try {
|
||||
const packagePath = join(settings.pluginDir, filename, 'package.json');
|
||||
const { version } = JSON.parse(readFileSync(packagePath, 'utf8'));
|
||||
logger.log(filename + '@' + version);
|
||||
} catch (e) {
|
||||
throw new Error('Unable to read package.json file for plugin ' + filename);
|
||||
}
|
||||
}
|
||||
});
|
||||
logger.log(''); //intentional blank line for aesthetics
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
{
|
||||
"_index": ".kibana",
|
||||
"_type": "config",
|
||||
"_id": "4.0.1-snapshot",
|
||||
"_id": "4.0.1-SNAPSHOT",
|
||||
"_score": 1,
|
||||
"_source": {
|
||||
"buildNum": 5921,
|
||||
|
|
|
@ -2,6 +2,7 @@ import _ from 'lodash';
|
|||
|
||||
module.exports = {
|
||||
'valueFormatter': _.identity,
|
||||
'geohashGridAgg': { 'vis': { 'params': {} } },
|
||||
'geoJson': {
|
||||
'type': 'FeatureCollection',
|
||||
'features': [
|
||||
|
|
|
@ -9,7 +9,7 @@ function VisDetailsSpyProvider(Notifier, $filter, $rootScope, config) {
|
|||
template: visDebugSpyPanelTemplate,
|
||||
order: 5,
|
||||
link: function ($scope, $el) {
|
||||
$scope.$watch('vis.getState() | json', function (json) {
|
||||
$scope.$watch('vis.getEnabledState() | json', function (json) {
|
||||
$scope.visStateJson = json;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -39,8 +39,9 @@ describe('plugins/elasticsearch', function () {
|
|||
upgradeDoc('4.0.0-rc2', '4.0.2', true);
|
||||
upgradeDoc('4.0.1', '4.1.0-rc', true);
|
||||
upgradeDoc('4.0.0-rc1', '4.0.0', true);
|
||||
upgradeDoc('4.0.0-rc1-snapshot', '4.0.0', false);
|
||||
upgradeDoc('4.1.0-rc1-snapshot', '4.1.0-rc1', false);
|
||||
upgradeDoc('4.0.0-rc1-SNAPSHOT', '4.0.0', false);
|
||||
upgradeDoc('4.1.0-rc1-SNAPSHOT', '4.1.0-rc1', false);
|
||||
upgradeDoc('5.0.0-alpha1', '5.0.0', false);
|
||||
|
||||
it('should handle missing _id field', function () {
|
||||
let doc = {
|
||||
|
|
|
@ -91,10 +91,18 @@ describe('plugins/elasticsearch', function () {
|
|||
});
|
||||
});
|
||||
|
||||
it('should resolve with undefined if the nothing is upgradeable', function () {
|
||||
const response = { hits: { hits: [ { _id: '4.0.1-beta1' }, { _id: '4.0.0-snapshot1' } ] } };
|
||||
it('should create new config if the nothing is upgradeable', function () {
|
||||
get.withArgs('pkg.buildNum').returns(9833);
|
||||
client.create.returns(Promise.resolve());
|
||||
const response = { hits: { hits: [ { _id: '4.0.1-alpha3' }, { _id: '4.0.1-beta1' }, { _id: '4.0.0-SNAPSHOT1' } ] } };
|
||||
return upgrade(response).then(function (resp) {
|
||||
expect(resp).to.be(undefined);
|
||||
sinon.assert.calledOnce(client.create);
|
||||
const params = client.create.args[0][0];
|
||||
expect(params).to.have.property('body');
|
||||
expect(params.body).to.have.property('buildNum', 9833);
|
||||
expect(params).to.have.property('index', '.my-kibana');
|
||||
expect(params).to.have.property('type', 'config');
|
||||
expect(params).to.have.property('id', '4.0.1');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -21,9 +21,9 @@ const versionChecks = [
|
|||
['2.0.1', '^2.0.0', true],
|
||||
['2.1.1', '^2.1.0', true],
|
||||
['2.2.0', '^2.1.0', true],
|
||||
['3.0.0-snapshot', '^2.1.0', false],
|
||||
['3.0.0-SNAPSHOT', '^2.1.0', false],
|
||||
['3.0.0', '^2.1.0', false],
|
||||
['2.10.20-snapshot', '^2.10.20', true],
|
||||
['2.10.20-SNAPSHOT', '^2.10.20', true],
|
||||
['2.10.999', '^2.10.20', true],
|
||||
];
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ const rcVersionRegex = /(\d+\.\d+\.\d+)\-rc(\d+)/i;
|
|||
|
||||
module.exports = function (server, doc) {
|
||||
const config = server.config();
|
||||
if (/beta|snapshot/i.test(doc._id)) return false;
|
||||
if (/alpha|beta|snapshot/i.test(doc._id)) return false;
|
||||
if (!doc._id) return false;
|
||||
if (doc._id === config.get('pkg.version')) return false;
|
||||
|
||||
|
|
|
@ -9,17 +9,21 @@ module.exports = function (server) {
|
|||
const client = server.plugins.elasticsearch.client;
|
||||
const config = server.config();
|
||||
|
||||
function createNewConfig() {
|
||||
return client.create({
|
||||
index: config.get('kibana.index'),
|
||||
type: 'config',
|
||||
body: { buildNum: config.get('pkg.buildNum') },
|
||||
id: config.get('pkg.version')
|
||||
});
|
||||
}
|
||||
|
||||
return function (response) {
|
||||
const newConfig = {};
|
||||
|
||||
// Check to see if there are any doc. If not then we set the build number and id
|
||||
if (response.hits.hits.length === 0) {
|
||||
return client.create({
|
||||
index: config.get('kibana.index'),
|
||||
type: 'config',
|
||||
body: { buildNum: config.get('pkg.buildNum') },
|
||||
id: config.get('pkg.version')
|
||||
});
|
||||
return createNewConfig();
|
||||
}
|
||||
|
||||
// if we already have a the current version in the index then we need to stop
|
||||
|
@ -30,9 +34,11 @@ module.exports = function (server) {
|
|||
if (devConfig) return Promise.resolve();
|
||||
|
||||
// Look for upgradeable configs. If none of them are upgradeable
|
||||
// then resolve with null.
|
||||
// then create a new one.
|
||||
const body = _.find(response.hits.hits, isUpgradeable.bind(null, server));
|
||||
if (!body) return Promise.resolve();
|
||||
if (!body) {
|
||||
return createNewConfig();
|
||||
}
|
||||
|
||||
// if the build number is still the template string (which it wil be in development)
|
||||
// then we need to set it to the max interger. Otherwise we will set it to the build num
|
||||
|
|
|
@ -27,6 +27,8 @@ export default function TileMapVisType(Private, getAppState, courier, config) {
|
|||
heatRadius: 25,
|
||||
heatBlur: 15,
|
||||
heatNormalizeData: true,
|
||||
mapZoom: 2,
|
||||
mapCenter: [15, 5],
|
||||
wms: config.get('visualization:tileMap:WMSdefaults')
|
||||
},
|
||||
mapTypes: ['Scaled Circle Markers', 'Shaded Circle Markers', 'Shaded Geohash Grid', 'Heatmap'],
|
||||
|
@ -46,54 +48,16 @@ export default function TileMapVisType(Private, getAppState, courier, config) {
|
|||
|
||||
pushFilter(filter, false, indexPatternName);
|
||||
},
|
||||
mapMoveEnd: function (event) {
|
||||
const agg = _.get(event, 'chart.geohashGridAgg');
|
||||
if (!agg) return;
|
||||
|
||||
agg.params.mapZoom = event.zoom;
|
||||
agg.params.mapCenter = [event.center.lat, event.center.lng];
|
||||
|
||||
const editableVis = agg.vis.getEditableVis();
|
||||
if (!editableVis) return;
|
||||
|
||||
const editableAgg = editableVis.aggs.byId[agg.id];
|
||||
if (editableAgg) {
|
||||
editableAgg.params.mapZoom = event.zoom;
|
||||
editableAgg.params.mapCenter = [event.center.lat, event.center.lng];
|
||||
}
|
||||
mapMoveEnd: function (event, uiState) {
|
||||
uiState.set('mapCenter', event.center);
|
||||
},
|
||||
mapZoomEnd: function (event) {
|
||||
const agg = _.get(event, 'chart.geohashGridAgg');
|
||||
if (!agg || !agg.params.autoPrecision) return;
|
||||
mapZoomEnd: function (event, uiState) {
|
||||
uiState.set('mapZoom', event.zoom);
|
||||
|
||||
// zoomPrecision maps event.zoom to a geohash precision value
|
||||
// event.limit is the configurable max geohash precision
|
||||
// default max precision is 7, configurable up to 12
|
||||
const zoomPrecision = {
|
||||
1: 2,
|
||||
2: 2,
|
||||
3: 2,
|
||||
4: 3,
|
||||
5: 3,
|
||||
6: 4,
|
||||
7: 4,
|
||||
8: 5,
|
||||
9: 5,
|
||||
10: 6,
|
||||
11: 6,
|
||||
12: 7,
|
||||
13: 7,
|
||||
14: 8,
|
||||
15: 9,
|
||||
16: 10,
|
||||
17: 11,
|
||||
18: 12
|
||||
};
|
||||
|
||||
const precision = config.get('visualization:tileMap:maxPrecision');
|
||||
agg.params.precision = Math.min(zoomPrecision[event.zoom], precision);
|
||||
|
||||
courier.fetch();
|
||||
const autoPrecision = _.get(event, 'chart.geohashGridAgg.params.autoPrecision');
|
||||
if (autoPrecision) {
|
||||
courier.fetch();
|
||||
}
|
||||
}
|
||||
},
|
||||
responseConverter: geoJsonConverter,
|
||||
|
|
|
@ -19,14 +19,13 @@ module.exports = function (kibana) {
|
|||
title: 'Kibana',
|
||||
listed: false,
|
||||
description: 'the kibana you know and love',
|
||||
//icon: 'plugins/kibana/settings/sections/about/barcode.svg',
|
||||
main: 'plugins/kibana/kibana',
|
||||
uses: [
|
||||
'visTypes',
|
||||
'spyModes',
|
||||
'fieldFormats',
|
||||
'navbarExtensions',
|
||||
'settingsSections',
|
||||
'managementSections',
|
||||
'docViews'
|
||||
],
|
||||
|
||||
|
@ -62,11 +61,12 @@ module.exports = function (kibana) {
|
|||
icon: 'plugins/kibana/assets/dashboard.svg',
|
||||
},
|
||||
{
|
||||
title: 'Settings',
|
||||
title: 'Management',
|
||||
order: 1000,
|
||||
url: '/app/kibana#/settings',
|
||||
url: '/app/kibana#/management',
|
||||
description: 'define index patterns, change config, and more',
|
||||
icon: 'plugins/kibana/assets/settings.svg',
|
||||
linkToLastSubUrl: false
|
||||
}
|
||||
],
|
||||
injectDefaultVars(server, options) {
|
||||
|
|
|
@ -15,7 +15,7 @@ uiModules
|
|||
const filterManager = Private(FilterManagerProvider);
|
||||
const notify = new Notifier();
|
||||
|
||||
const services = require('plugins/kibana/settings/saved_object_registry').all().map(function (serviceObj) {
|
||||
const services = require('plugins/kibana/management/saved_object_registry').all().map(function (serviceObj) {
|
||||
const service = $injector.get(serviceObj.service);
|
||||
return {
|
||||
type: service.type,
|
||||
|
@ -55,6 +55,10 @@ uiModules
|
|||
// create child ui state from the savedObj
|
||||
const uiState = panelConfig.uiState || {};
|
||||
$scope.uiState = $scope.parentUiState.createChild(getPanelId(panelConfig.panel), uiState, true);
|
||||
const panelSavedVis = _.get(panelConfig, 'savedObj.vis'); // Sometimes this will be a search, and undef
|
||||
if (panelSavedVis) {
|
||||
panelSavedVis.setUiState($scope.uiState);
|
||||
}
|
||||
|
||||
$scope.filter = function (field, value, operator) {
|
||||
const index = $scope.savedObj.searchSource.get('index').id;
|
||||
|
@ -75,7 +79,7 @@ uiModules
|
|||
const service = _.find(services, { type: type });
|
||||
if (!service) return;
|
||||
|
||||
$scope.editUrl = '#settings/objects/' + service.name + '/' + id + '?notFound=' + e.savedObjectType;
|
||||
$scope.editUrl = '#management/kibana/objects/' + service.name + '/' + id + '?notFound=' + e.savedObjectType;
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -68,6 +68,9 @@ app.directive('dashboardApp', function (Notifier, courier, AppState, timefilter,
|
|||
if (dash.timeRestore && dash.timeTo && dash.timeFrom && !getAppState.previouslyStored()) {
|
||||
timefilter.time.to = dash.timeTo;
|
||||
timefilter.time.from = dash.timeFrom;
|
||||
if (dash.refreshInterval) {
|
||||
timefilter.refreshInterval = dash.refreshInterval;
|
||||
}
|
||||
}
|
||||
|
||||
$scope.$on('$destroy', dash.destroy);
|
||||
|
@ -204,10 +207,12 @@ app.directive('dashboardApp', function (Notifier, courier, AppState, timefilter,
|
|||
$state.title = dash.id = dash.title;
|
||||
$state.save();
|
||||
|
||||
const timeRestoreObj = _.pick(timefilter.refreshInterval, ['display', 'pause', 'section', 'value']);
|
||||
dash.panelsJSON = angular.toJson($state.panels);
|
||||
dash.uiStateJSON = angular.toJson($uiState.getChanges());
|
||||
dash.timeFrom = dash.timeRestore ? timefilter.time.from : undefined;
|
||||
dash.timeTo = dash.timeRestore ? timefilter.time.to : undefined;
|
||||
dash.refreshInterval = dash.timeRestore ? timeRestoreObj : undefined;
|
||||
dash.optionsJSON = angular.toJson($state.options);
|
||||
|
||||
dash.save()
|
||||
|
|
|
@ -33,6 +33,7 @@ module.factory('SavedDashboard', function (courier, config) {
|
|||
timeRestore: false,
|
||||
timeTo: undefined,
|
||||
timeFrom: undefined,
|
||||
refreshInterval: undefined
|
||||
},
|
||||
|
||||
// if an indexPattern was saved with the searchsource of a SavedDashboard
|
||||
|
@ -56,6 +57,15 @@ module.factory('SavedDashboard', function (courier, config) {
|
|||
timeRestore: 'boolean',
|
||||
timeTo: 'string',
|
||||
timeFrom: 'string',
|
||||
refreshInterval: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
display: {type: 'string'},
|
||||
pause: { type: 'boolean'},
|
||||
section: { type: 'integer'},
|
||||
value: { type: 'integer'}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SavedDashboard.searchsource = true;
|
||||
|
|
|
@ -9,7 +9,7 @@ const module = uiModules.get('app/dashboard');
|
|||
|
||||
// Register this service with the saved object registry so it can be
|
||||
// edited by the object editor.
|
||||
require('plugins/kibana/settings/saved_object_registry').register({
|
||||
require('plugins/kibana/management/saved_object_registry').register({
|
||||
service: 'savedDashboards',
|
||||
title: 'dashboards'
|
||||
});
|
||||
|
|
|
@ -65,7 +65,7 @@ uiRoutes
|
|||
return savedSearches.get($route.current.params.id)
|
||||
.catch(courier.redirectWhenMissing({
|
||||
'search': '/discover',
|
||||
'index-pattern': '/settings/objects/savedSearches/' + $route.current.params.id
|
||||
'index-pattern': '/management/kibana/objects/savedSearches/' + $route.current.params.id
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
@ -496,7 +496,7 @@ app.controller('discover', function ($scope, config, courier, $route, $window, N
|
|||
|
||||
// we have a vis, just modify the aggs
|
||||
if ($scope.vis) {
|
||||
const visState = $scope.vis.getState();
|
||||
const visState = $scope.vis.getEnabledState();
|
||||
visState.aggs = visStateAggs;
|
||||
|
||||
$scope.vis.setState(visState);
|
||||
|
|
13
src/plugins/kibana/public/discover/directives/no_results.js
Normal file
13
src/plugins/kibana/public/discover/directives/no_results.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
import _ from 'lodash';
|
||||
import $ from 'jquery';
|
||||
import uiModules from 'ui/modules';
|
||||
import noResultsTemplate from '../partials/no_results.html';
|
||||
|
||||
uiModules
|
||||
.get('apps/discover')
|
||||
.directive('discoverNoResults', function () {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: noResultsTemplate
|
||||
};
|
||||
});
|
|
@ -56,58 +56,7 @@
|
|||
|
||||
<div class="discover-wrapper col-md-10">
|
||||
<div class="discover-content">
|
||||
<!-- no results -->
|
||||
<div ng-show="resultState === 'none'">
|
||||
<div class="col-md-10 col-md-offset-1">
|
||||
|
||||
<h1>No results found <i aria-hidden="true" class="fa fa-meh-o"></i></h1>
|
||||
|
||||
<p>
|
||||
Unfortunately I could not find any results matching your search. I tried really hard. I looked all over the place and frankly, I just couldn't find anything good. Help me, help you. Here are some ideas:
|
||||
</p>
|
||||
|
||||
<div class="shard-failures" ng-show="failures">
|
||||
<h3>Shard Failures</h3>
|
||||
<p>The following shard failures ocurred:</p>
|
||||
<ul>
|
||||
<li ng-repeat="failure in failures | limitTo: failuresShown"><strong>Index:</strong> {{failure.index}} <strong>Shard:</strong> {{failure.shard}} <strong>Reason:</strong> {{failure.reason}} </li>
|
||||
</ul>
|
||||
<a ng-click="showAllFailures()" ng-if="failures.length > failuresShown" title="Show More">Show More</a>
|
||||
<a ng-click="showLessFailures()" ng-if="failures.length === failuresShown && failures.length > 5" title="Show Less">Show Less</a>
|
||||
</div>
|
||||
|
||||
<div ng-show="opts.timefield">
|
||||
<p>
|
||||
<h3>Expand your time range</h3>
|
||||
<p>I see you are looking at an index with a date field. It is possible your query does not match anything in the current time range, or that there is no data at all in the currently selected time range. Try selecting a wider time range by opening the time picker <i aria-hidden="true" class="fa fa-clock-o"></i> in the top right corner of your screen.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h3>Refine your query</h3>
|
||||
<p>
|
||||
The search bar at the top uses Elasticsearch's support for Lucene <a href="http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-syntax" target="_blank">Query String syntax</a>. Let's say we're searching web server logs that have been parsed into a few fields.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<h4>Examples:</h4>
|
||||
Find requests that contain the number 200, in any field:
|
||||
<pre>200</pre>
|
||||
|
||||
Or we can search in a specific field. Find 200 in the status field:
|
||||
<pre>status:200</pre>
|
||||
|
||||
Find all status codes between 400-499:
|
||||
<pre>status:[400 TO 499]</pre>
|
||||
|
||||
Find status codes 400-499 with the extension php:
|
||||
<pre>status:[400 TO 499] AND extension:PHP</pre>
|
||||
|
||||
Or HTML
|
||||
<pre>status:[400 TO 499] AND (extension:php OR extension:html)</pre>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<discover-no-results ng-show="resultState === 'none'"></discover-no-results>
|
||||
|
||||
<!-- loading -->
|
||||
<div ng-show="resultState === 'loading'">
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'plugins/kibana/discover/saved_searches/saved_searches';
|
||||
import 'plugins/kibana/discover/directives/no_results';
|
||||
import 'plugins/kibana/discover/directives/timechart';
|
||||
import 'ui/navbar_extensions';
|
||||
import 'ui/collapsible_sidebar';
|
||||
|
|
51
src/plugins/kibana/public/discover/partials/no_results.html
Normal file
51
src/plugins/kibana/public/discover/partials/no_results.html
Normal file
|
@ -0,0 +1,51 @@
|
|||
<div>
|
||||
<div class="col-md-10 col-md-offset-1" data-test-subj="discoverNoResults">
|
||||
|
||||
<h1>No results found <i aria-hidden="true" class="fa fa-meh-o"></i></h1>
|
||||
|
||||
<p>
|
||||
Unfortunately I could not find any results matching your search. I tried really hard. I looked all over the place and frankly, I just couldn't find anything good. Help me, help you. Here are some ideas:
|
||||
</p>
|
||||
|
||||
<div class="shard-failures" ng-show="failures">
|
||||
<h3>Shard Failures</h3>
|
||||
<p>The following shard failures ocurred:</p>
|
||||
<ul>
|
||||
<li ng-repeat="failure in failures | limitTo: failuresShown"><strong>Index:</strong> {{failure.index}} <strong>Shard:</strong> {{failure.shard}} <strong>Reason:</strong> {{failure.reason}} </li>
|
||||
</ul>
|
||||
<a ng-click="showAllFailures()" ng-if="failures.length > failuresShown" title="Show More">Show More</a>
|
||||
<a ng-click="showLessFailures()" ng-if="failures.length === failuresShown && failures.length > 5" title="Show Less">Show Less</a>
|
||||
</div>
|
||||
|
||||
<div ng-show="opts.timefield">
|
||||
<p>
|
||||
<h3>Expand your time range</h3>
|
||||
<p>I see you are looking at an index with a date field. It is possible your query does not match anything in the current time range, or that there is no data at all in the currently selected time range. Click the button below to open the time picker. For future reference you can open the time picker by clicking on the <a class="btn btn-xs navbtn" ng-click="kbnTopNav.toggle('filter')" aria-expanded="kbnTopNav.is('filter')" aria-label="time picker" data-test-subj="discoverNoResultsTimefilter"><i aria-hidden="true" class="fa fa-clock-o"></i> time picker</a> button in the top right corner of your screen.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h3>Refine your query</h3>
|
||||
<p>
|
||||
The search bar at the top uses Elasticsearch's support for Lucene <a href="http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-syntax" target="_blank">Query String syntax</a>. Let's say we're searching web server logs that have been parsed into a few fields.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<h4>Examples:</h4>
|
||||
Find requests that contain the number 200, in any field:
|
||||
<pre>200</pre>
|
||||
|
||||
Or we can search in a specific field. Find 200 in the status field:
|
||||
<pre>status:200</pre>
|
||||
|
||||
Find all status codes between 400-499:
|
||||
<pre>status:[400 TO 499]</pre>
|
||||
|
||||
Find status codes 400-499 with the extension php:
|
||||
<pre>status:[400 TO 499] AND extension:PHP</pre>
|
||||
|
||||
Or HTML
|
||||
<pre>status:[400 TO 499] AND (extension:php OR extension:html)</pre>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
|
@ -11,7 +11,7 @@ const module = uiModules.get('discover/saved_searches', [
|
|||
|
||||
// Register this service with the saved object registry so it can be
|
||||
// edited by the object editor.
|
||||
require('plugins/kibana/settings/saved_object_registry').register({
|
||||
require('plugins/kibana/management/saved_object_registry').register({
|
||||
service: 'savedSearches',
|
||||
title: 'searches'
|
||||
});
|
||||
|
|
|
@ -11,7 +11,7 @@ import 'ui/autoload/all';
|
|||
import 'plugins/kibana/discover/index';
|
||||
import 'plugins/kibana/visualize/index';
|
||||
import 'plugins/kibana/dashboard/index';
|
||||
import 'plugins/kibana/settings/index';
|
||||
import 'plugins/kibana/management/index';
|
||||
import 'plugins/kibana/doc';
|
||||
import 'ui/vislib';
|
||||
import 'ui/agg_response';
|
||||
|
|
23
src/plugins/kibana/public/management/app.html
Normal file
23
src/plugins/kibana/public/management/app.html
Normal file
|
@ -0,0 +1,23 @@
|
|||
<div class="app-container">
|
||||
<nav class="navbar navbar-default navbar-static-top subnav" data-test-subj="managementNav">
|
||||
<bread-crumbs omit-current-page="true"></bread-crumbs>
|
||||
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="current-page" ng-hide="sectionName">
|
||||
{{::section.display}}
|
||||
</li>
|
||||
|
||||
<li
|
||||
ng-if="sectionName"
|
||||
ng-repeat="item in section.items.inOrder"
|
||||
ng-class="item.class">
|
||||
|
||||
<a class="navbar-link" kbn-href="{{::item.url}}" data-test-subj="{{::item.name}}">
|
||||
{{::item.display}}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<div role="main" class="management-container" ng-transclude></div>
|
||||
</div>
|
64
src/plugins/kibana/public/management/index.js
Normal file
64
src/plugins/kibana/public/management/index.js
Normal file
|
@ -0,0 +1,64 @@
|
|||
import _ from 'lodash';
|
||||
|
||||
import 'plugins/kibana/management/sections';
|
||||
import 'plugins/kibana/management/styles/main.less';
|
||||
import 'ui/filters/start_from';
|
||||
import 'ui/field_editor';
|
||||
import 'plugins/kibana/management/sections/indices/_indexed_fields';
|
||||
import 'plugins/kibana/management/sections/indices/_scripted_fields';
|
||||
import 'ui/directives/bread_crumbs';
|
||||
import uiRoutes from 'ui/routes';
|
||||
import uiModules from 'ui/modules';
|
||||
import appTemplate from 'plugins/kibana/management/app.html';
|
||||
import landingTemplate from 'plugins/kibana/management/landing.html';
|
||||
import chrome from 'ui/chrome/chrome';
|
||||
import management from 'ui/management';
|
||||
|
||||
uiRoutes
|
||||
.when('/management', {
|
||||
template: landingTemplate
|
||||
});
|
||||
|
||||
require('ui/index_patterns/route_setup/load_default')({
|
||||
notRequiredRe: /^\/management\/data\//,
|
||||
whenMissingRedirectTo: '/management/data/index'
|
||||
});
|
||||
|
||||
uiModules
|
||||
.get('apps/management')
|
||||
.directive('kbnManagementApp', function (Private, $route, $location, timefilter, buildNum, buildSha) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: appTemplate,
|
||||
transclude: true,
|
||||
scope: {
|
||||
sectionName: '@section'
|
||||
},
|
||||
|
||||
link: function ($scope) {
|
||||
timefilter.enabled = false;
|
||||
$scope.sections = management.items.inOrder;
|
||||
$scope.section = management.getSection($scope.sectionName) || management;
|
||||
|
||||
if ($scope.section) {
|
||||
$scope.section.items.forEach(item => {
|
||||
item.class = `#${$location.path()}`.indexOf(item.url) > -1 ? 'active' : undefined;
|
||||
});
|
||||
}
|
||||
|
||||
management.getSection('kibana').info = `Build ${buildNum}, Commit SHA ${buildSha.substr(0, 8)}`;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
uiModules
|
||||
.get('apps/management')
|
||||
.directive('kbnManagementLanding', function (kbnVersion) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function ($scope) {
|
||||
$scope.sections = management.items.inOrder;
|
||||
$scope.kbnVersion = kbnVersion;
|
||||
}
|
||||
};
|
||||
});
|
45
src/plugins/kibana/public/management/landing.html
Normal file
45
src/plugins/kibana/public/management/landing.html
Normal file
|
@ -0,0 +1,45 @@
|
|||
<kbn-management-app>
|
||||
<kbn-management-landing>
|
||||
<div class="product-overview">
|
||||
<span class="kibana-version">Version: {{::kbnVersion}}</span>
|
||||
</div>
|
||||
<div class="management-sections">
|
||||
<div
|
||||
ng-if="section.items.length > 0"
|
||||
ng-repeat="section in sections"
|
||||
ng-class="{ 'management-section-info-expanded': section.showInfo }"
|
||||
class="col-xs-12 management-section management-section-{{::section.id}}">
|
||||
|
||||
<div class="panel panel-product management-panel-product">
|
||||
<div class="panel-heading panel-heading-{{::section.id}}">
|
||||
{{::section.display}}
|
||||
|
||||
<i
|
||||
class="fa fa-info-circle pull-right panel-heading-icon"
|
||||
ng-click="section.showInfo = !!!section.showInfo"
|
||||
ng-if="section.info">
|
||||
</i>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<ul class="management-section-items list-unstyled">
|
||||
<li
|
||||
class="col-xs-4 col-md-3"
|
||||
ng-repeat="item in section.items.inOrder">
|
||||
|
||||
<a class="management-link" kbn-href="{{::item.url}}">
|
||||
{{::item.display}}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="management-section-info">
|
||||
{{::section.info}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</kbn-management-landing>
|
||||
</kbn-management-app>
|
3
src/plugins/kibana/public/management/sections/index.js
Normal file
3
src/plugins/kibana/public/management/sections/index.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
import 'plugins/kibana/management/sections/settings';
|
||||
import 'plugins/kibana/management/sections/objects';
|
||||
import 'plugins/kibana/management/sections/indices';
|
|
@ -1,6 +1,6 @@
|
|||
<kbn-settings-app section="indices">
|
||||
<kbn-settings-indices>
|
||||
<div ng-controller="settingsIndicesCreate" class="kbn-settings-indices-create">
|
||||
<kbn-management-app section="data">
|
||||
<kbn-management-indices>
|
||||
<div ng-controller="managementIndicesCreate" class="kbn-management-indices-create">
|
||||
<div class="page-header">
|
||||
<h1>Configure an index pattern</h1>
|
||||
In order to use Kibana you must configure at least one index pattern. Index patterns are
|
||||
|
@ -177,5 +177,5 @@
|
|||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</kbn-settings-indices>
|
||||
</kbn-settings-app>
|
||||
</kbn-management-indices>
|
||||
</kbn-management-app>
|
|
@ -3,21 +3,20 @@ import moment from 'moment';
|
|||
import { IndexPatternMissingIndices } from 'ui/errors';
|
||||
import 'ui/directives/validate_index_name';
|
||||
import 'ui/directives/auto_select_if_only_one';
|
||||
import PluginsKibanaSettingsSectionsIndicesRefreshKibanaIndexProvider from 'plugins/kibana/settings/sections/indices/_refresh_kibana_index';
|
||||
import RefreshKibanaIndex from 'plugins/kibana/management/sections/indices/_refresh_kibana_index';
|
||||
import uiRoutes from 'ui/routes';
|
||||
import uiModules from 'ui/modules';
|
||||
import createTemplate from 'plugins/kibana/settings/sections/indices/_create.html';
|
||||
|
||||
import createTemplate from 'plugins/kibana/management/sections/indices/_create.html';
|
||||
|
||||
uiRoutes
|
||||
.when('/settings/indices/', {
|
||||
.when('/management/data/index/', {
|
||||
template: createTemplate
|
||||
});
|
||||
|
||||
uiModules.get('apps/settings')
|
||||
.controller('settingsIndicesCreate', function ($scope, kbnUrl, Private, Notifier, indexPatterns, es, config, Promise) {
|
||||
uiModules.get('apps/management')
|
||||
.controller('managementIndicesCreate', function ($scope, kbnUrl, Private, Notifier, indexPatterns, es, config, Promise) {
|
||||
const notify = new Notifier();
|
||||
const refreshKibanaIndex = Private(PluginsKibanaSettingsSectionsIndicesRefreshKibanaIndexProvider);
|
||||
const refreshKibanaIndex = Private(RefreshKibanaIndex);
|
||||
const intervals = indexPatterns.intervals;
|
||||
let samplePromise;
|
||||
|
||||
|
@ -73,7 +72,7 @@ uiModules.get('apps/settings')
|
|||
config.set('defaultIndex', indexPattern.id);
|
||||
}
|
||||
indexPatterns.cache.clear(indexPattern.id);
|
||||
kbnUrl.change('/settings/indices/' + indexPattern.id);
|
||||
kbnUrl.change('/management/kibana/indices/' + indexPattern.id);
|
||||
});
|
||||
}
|
||||
});
|
|
@ -1,13 +1,13 @@
|
|||
<kbn-settings-app section="indices">
|
||||
<kbn-settings-indices>
|
||||
<div ng-controller="settingsIndicesEdit">
|
||||
<kbn-management-app section="kibana">
|
||||
<kbn-management-indices>
|
||||
<div ng-controller="managementIndicesEdit">
|
||||
<div class="page-header">
|
||||
<kbn-settings-index-header
|
||||
<kbn-management-index-header
|
||||
index-pattern="indexPattern"
|
||||
set-default="setDefaultPattern()"
|
||||
refresh-fields="indexPattern.refreshFields()"
|
||||
delete="removePattern()">
|
||||
</kbn-settings-index-header>
|
||||
</kbn-management-index-header>
|
||||
|
||||
<p>
|
||||
This page lists every field in the <strong>{{::indexPattern.id}}</strong>
|
||||
|
@ -38,7 +38,7 @@
|
|||
<br />
|
||||
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="kbn-settings-tab" ng-class="{ active: state.tab === fieldType.index }" ng-repeat="fieldType in fieldTypes">
|
||||
<li class="kbn-management-tab" ng-class="{ active: state.tab === fieldType.index }" ng-repeat="fieldType in fieldTypes">
|
||||
<a ng-click="changeTab(fieldType)">
|
||||
{{ fieldType.title }}
|
||||
<small>({{ fieldType.count }})</small>
|
||||
|
@ -50,5 +50,5 @@
|
|||
<scripted-fields ng-show="state.tab == 'scriptedFields'" class="fields scripted-fields"></scripted-fields>
|
||||
|
||||
</div>
|
||||
</kbn-settings-indices>
|
||||
</kbn-settings-app>
|
||||
</kbn-management-indices>
|
||||
</kbn-management-app>
|
|
@ -1,38 +1,44 @@
|
|||
import _ from 'lodash';
|
||||
import 'plugins/kibana/settings/sections/indices/_indexed_fields';
|
||||
import 'plugins/kibana/settings/sections/indices/_scripted_fields';
|
||||
import 'plugins/kibana/settings/sections/indices/_index_header';
|
||||
import PluginsKibanaSettingsSectionsIndicesRefreshKibanaIndexProvider from 'plugins/kibana/settings/sections/indices/_refresh_kibana_index';
|
||||
import 'plugins/kibana/management/sections/indices/_indexed_fields';
|
||||
import 'plugins/kibana/management/sections/indices/_scripted_fields';
|
||||
import 'plugins/kibana/management/sections/indices/_index_header';
|
||||
import RefreshKibanaIndex from 'plugins/kibana/management/sections/indices/_refresh_kibana_index';
|
||||
import UrlProvider from 'ui/url';
|
||||
import PluginsKibanaSettingsSectionsIndicesFieldTypesProvider from 'plugins/kibana/settings/sections/indices/_field_types';
|
||||
import IndicesFieldTypesProvider from 'plugins/kibana/management/sections/indices/_field_types';
|
||||
import uiRoutes from 'ui/routes';
|
||||
import uiModules from 'ui/modules';
|
||||
import editTemplate from 'plugins/kibana/settings/sections/indices/_edit.html';
|
||||
import editTemplate from 'plugins/kibana/management/sections/indices/_edit.html';
|
||||
|
||||
uiRoutes
|
||||
.when('/settings/indices/:indexPatternId', {
|
||||
.when('/management/kibana/indices/:indexPatternId?', {
|
||||
template: editTemplate,
|
||||
resolve: {
|
||||
indexPattern: function ($route, courier) {
|
||||
return courier.indexPatterns.get($route.current.params.indexPatternId)
|
||||
.catch(courier.redirectWhenMissing('/settings/indices'));
|
||||
indexPattern: function ($route, config, courier) {
|
||||
const params = $route.current.params;
|
||||
|
||||
if (typeof params.indexPatternId === 'undefined') {
|
||||
params.indexPatternId = config.get('defaultIndex');
|
||||
}
|
||||
|
||||
return courier.indexPatterns.get(params.indexPatternId)
|
||||
.catch(courier.redirectWhenMissing('/management/data/index'));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
uiModules.get('apps/settings')
|
||||
.controller('settingsIndicesEdit', function ($scope, $location, $route, config, courier, Notifier, Private, AppState, docTitle) {
|
||||
uiModules.get('apps/management')
|
||||
.controller('managementIndicesEdit', function ($scope, $location, $route, config, courier, Notifier, Private, AppState, docTitle) {
|
||||
|
||||
const notify = new Notifier();
|
||||
const $state = $scope.state = new AppState();
|
||||
const refreshKibanaIndex = Private(PluginsKibanaSettingsSectionsIndicesRefreshKibanaIndexProvider);
|
||||
const refreshKibanaIndex = Private(RefreshKibanaIndex);
|
||||
|
||||
$scope.kbnUrl = Private(UrlProvider);
|
||||
$scope.indexPattern = $route.current.locals.indexPattern;
|
||||
docTitle.change($scope.indexPattern.id);
|
||||
const otherIds = _.without($route.current.locals.indexPatternIds, $scope.indexPattern.id);
|
||||
|
||||
const fieldTypes = Private(PluginsKibanaSettingsSectionsIndicesFieldTypesProvider);
|
||||
const fieldTypes = Private(IndicesFieldTypesProvider);
|
||||
$scope.$watch('indexPattern.fields', function () {
|
||||
$scope.fieldTypes = fieldTypes($scope.indexPattern);
|
||||
});
|
||||
|
@ -65,7 +71,7 @@ uiModules.get('apps/settings')
|
|||
courier.indexPatterns.delete($scope.indexPattern)
|
||||
.then(refreshKibanaIndex)
|
||||
.then(function () {
|
||||
$location.url('/settings/indices');
|
||||
$location.url('/management/data/index');
|
||||
})
|
||||
.catch(notify.fatal);
|
||||
};
|
|
@ -1,7 +1,7 @@
|
|||
<kbn-settings-app section="indices">
|
||||
<kbn-settings-indices>
|
||||
<kbn-management-app section="kibana">
|
||||
<kbn-management-indices>
|
||||
<div class="page-header">
|
||||
<kbn-settings-index-header index-pattern="fieldSettings.indexPattern"></kbn-settings-index-header>
|
||||
<kbn-management-index-header index-pattern="fieldSettings.indexPattern"></kbn-management-index-header>
|
||||
|
||||
<h2 ng-if="fieldSettings.mode === 'create'">
|
||||
Create {{ fieldSettings.field.scripted ? 'Scripted ' : '' }}Field
|
||||
|
@ -14,5 +14,5 @@
|
|||
|
||||
<field-editor index-pattern="fieldSettings.indexPattern" field="fieldSettings.field"></field-editor>
|
||||
|
||||
</kbn-settings-indices>
|
||||
</kbn-settings-app>
|
||||
</kbn-management-indices>
|
||||
</kbn-management-app>
|
|
@ -1,19 +1,19 @@
|
|||
import 'ui/field_editor';
|
||||
import 'plugins/kibana/settings/sections/indices/_index_header';
|
||||
import 'plugins/kibana/management/sections/indices/_index_header';
|
||||
import IndexPatternsFieldProvider from 'ui/index_patterns/_field';
|
||||
import UrlProvider from 'ui/url';
|
||||
import uiRoutes from 'ui/routes';
|
||||
import fieldEditorTemplate from 'plugins/kibana/settings/sections/indices/_field_editor.html';
|
||||
import fieldEditorTemplate from 'plugins/kibana/management/sections/indices/_field_editor.html';
|
||||
|
||||
uiRoutes
|
||||
.when('/settings/indices/:indexPatternId/field/:fieldName', { mode: 'edit' })
|
||||
.when('/settings/indices/:indexPatternId/create-field/', { mode: 'create' })
|
||||
.defaults(/settings\/indices\/[^\/]+\/(field|create-field)(\/|$)/, {
|
||||
.when('/management/kibana/indices/:indexPatternId/field/:fieldName', { mode: 'edit' })
|
||||
.when('/management/kibana/indices/:indexPatternId/create-field/', { mode: 'create' })
|
||||
.defaults(/management\/kibana\/indices\/[^\/]+\/(field|create-field)(\/|$)/, {
|
||||
template: fieldEditorTemplate,
|
||||
resolve: {
|
||||
indexPattern: function ($route, courier) {
|
||||
return courier.indexPatterns.get($route.current.params.indexPatternId)
|
||||
.catch(courier.redirectWhenMissing('/settings/indices'));
|
||||
.catch(courier.redirectWhenMissing('/management/kibana/indices'));
|
||||
}
|
||||
},
|
||||
controllerAs: 'fieldSettings',
|
||||
|
@ -22,7 +22,6 @@ uiRoutes
|
|||
const notify = new Notifier({ location: 'Field Editor' });
|
||||
const kbnUrl = Private(UrlProvider);
|
||||
|
||||
|
||||
this.mode = $route.current.mode;
|
||||
this.indexPattern = $route.current.locals.indexPattern;
|
||||
|
||||
|
@ -54,4 +53,3 @@ uiRoutes
|
|||
};
|
||||
}
|
||||
});
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
import uiModules from 'ui/modules';
|
||||
import indexHeaderTemplate from 'plugins/kibana/settings/sections/indices/_index_header.html';
|
||||
import indexHeaderTemplate from 'plugins/kibana/management/sections/indices/_index_header.html';
|
||||
uiModules
|
||||
.get('apps/settings')
|
||||
.directive('kbnSettingsIndexHeader', function (config) {
|
||||
.get('apps/management')
|
||||
.directive('kbnManagementIndexHeader', function (config) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: indexHeaderTemplate,
|
|
@ -1,12 +1,12 @@
|
|||
import _ from 'lodash';
|
||||
import 'ui/paginated_table';
|
||||
import nameHtml from 'plugins/kibana/settings/sections/indices/_field_name.html';
|
||||
import typeHtml from 'plugins/kibana/settings/sections/indices/_field_type.html';
|
||||
import controlsHtml from 'plugins/kibana/settings/sections/indices/_field_controls.html';
|
||||
import nameHtml from 'plugins/kibana/management/sections/indices/_field_name.html';
|
||||
import typeHtml from 'plugins/kibana/management/sections/indices/_field_type.html';
|
||||
import controlsHtml from 'plugins/kibana/management/sections/indices/_field_controls.html';
|
||||
import uiModules from 'ui/modules';
|
||||
import indexedFieldsTemplate from 'plugins/kibana/settings/sections/indices/_indexed_fields.html';
|
||||
import indexedFieldsTemplate from 'plugins/kibana/management/sections/indices/_indexed_fields.html';
|
||||
|
||||
uiModules.get('apps/settings')
|
||||
uiModules.get('apps/management')
|
||||
.directive('indexedFields', function ($filter) {
|
||||
const yesTemplate = '<i class="fa fa-check" aria-label="yes"></i>';
|
||||
const noTemplate = '';
|
|
@ -1,12 +1,12 @@
|
|||
import _ from 'lodash';
|
||||
import 'ui/paginated_table';
|
||||
import popularityHtml from 'plugins/kibana/settings/sections/indices/_field_popularity.html';
|
||||
import controlsHtml from 'plugins/kibana/settings/sections/indices/_field_controls.html';
|
||||
import dateScripts from 'plugins/kibana/settings/sections/indices/_date_scripts';
|
||||
import popularityHtml from 'plugins/kibana/management/sections/indices/_field_popularity.html';
|
||||
import controlsHtml from 'plugins/kibana/management/sections/indices/_field_controls.html';
|
||||
import dateScripts from 'plugins/kibana/management/sections/indices/_date_scripts';
|
||||
import uiModules from 'ui/modules';
|
||||
import scriptedFieldsTemplate from 'plugins/kibana/settings/sections/indices/_scripted_fields.html';
|
||||
import scriptedFieldsTemplate from 'plugins/kibana/management/sections/indices/_scripted_fields.html';
|
||||
|
||||
uiModules.get('apps/settings')
|
||||
uiModules.get('apps/management')
|
||||
.directive('scriptedFields', function (kbnUrl, Notifier, $filter) {
|
||||
const rowScopes = []; // track row scopes, so they can be destroyed as needed
|
||||
const filter = $filter('filter');
|
||||
|
@ -19,7 +19,7 @@ uiModules.get('apps/settings')
|
|||
scope: true,
|
||||
link: function ($scope) {
|
||||
|
||||
const fieldCreatorPath = '/settings/indices/{{ indexPattern }}/scriptedField';
|
||||
const fieldCreatorPath = '/management/kibana/indices/{{ indexPattern }}/scriptedField';
|
||||
const fieldEditorPath = fieldCreatorPath + '/{{ fieldName }}';
|
||||
|
||||
$scope.perPage = 25;
|
|
@ -2,10 +2,9 @@
|
|||
<div class="sidebar-list">
|
||||
<div class="sidebar-list-header">
|
||||
<h5>
|
||||
Index Patterns
|
||||
<a
|
||||
ng-if="editingId"
|
||||
href="#/settings/indices"
|
||||
href="#/management/data/index"
|
||||
class="btn btn-primary btn-xs"
|
||||
aria-label="Add New">
|
||||
<span class="sr-only">Add New</span>
|
|
@ -0,0 +1,64 @@
|
|||
import management from 'ui/management';
|
||||
import 'plugins/kibana/management/sections/indices/_create';
|
||||
import 'plugins/kibana/management/sections/indices/_edit';
|
||||
import 'plugins/kibana/management/sections/indices/_field_editor';
|
||||
import uiRoutes from 'ui/routes';
|
||||
import uiModules from 'ui/modules';
|
||||
import indexTemplate from 'plugins/kibana/management/sections/indices/index.html';
|
||||
|
||||
const indexPatternsResolutions = {
|
||||
indexPatternIds: function (courier) {
|
||||
return courier.indexPatterns.getIds();
|
||||
}
|
||||
};
|
||||
|
||||
// add a dependency to all of the subsection routes
|
||||
uiRoutes
|
||||
.defaults(/management\/kibana\/indices/, {
|
||||
resolve: indexPatternsResolutions
|
||||
});
|
||||
|
||||
uiRoutes
|
||||
.defaults(/management\/data\/index/, {
|
||||
resolve: indexPatternsResolutions
|
||||
});
|
||||
|
||||
// wrapper directive, which sets some global stuff up like the left nav
|
||||
uiModules.get('apps/management')
|
||||
.directive('kbnManagementIndices', function ($route, config, kbnUrl) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
transclude: true,
|
||||
template: indexTemplate,
|
||||
link: function ($scope) {
|
||||
$scope.editingId = $route.current.params.indexPatternId;
|
||||
config.bindToScope($scope, 'defaultIndex');
|
||||
|
||||
$scope.$watch('defaultIndex', function () {
|
||||
const ids = $route.current.locals.indexPatternIds;
|
||||
$scope.indexPatternList = ids.map(function (id) {
|
||||
return {
|
||||
id: id,
|
||||
url: kbnUrl.eval('#/management/kibana/indices/{{id}}', {id: id}),
|
||||
class: 'sidebar-item-title ' + ($scope.editingId === id ? 'active' : ''),
|
||||
default: $scope.defaultIndex === id
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
$scope.$emit('application.load');
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
management.getSection('data').register('indices', {
|
||||
display: 'Existing Data',
|
||||
order: 0,
|
||||
path: 'data/index/'
|
||||
});
|
||||
|
||||
management.getSection('kibana').register('indices', {
|
||||
display: 'Index Patterns',
|
||||
order: 0,
|
||||
path: 'kibana/indices/'
|
||||
});
|
|
@ -1,5 +1,5 @@
|
|||
<kbn-settings-app section="objects">
|
||||
<kbn-settings-objects class="container">
|
||||
<kbn-management-app section="kibana">
|
||||
<kbn-management-objects class="container-fluid">
|
||||
<div class="header">
|
||||
<h2 class="title">Edit Saved Objects</h2>
|
||||
<button class="btn btn-default controls" ng-click="exportAll()"><i aria-hidden="true" class="fa fa-download"></i> Export Everything</button>
|
||||
|
@ -17,7 +17,7 @@
|
|||
</form>
|
||||
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="kbn-settings-tab" ng-class="{ active: state.tab === service.title }" ng-repeat="service in services">
|
||||
<li class="kbn-management-tab" ng-class="{ active: state.tab === service.title }" ng-repeat="service in services">
|
||||
<a title="{{ service.title }}" ng-click="changeTab(service)">{{ service.title }}
|
||||
<small>
|
||||
({{service.data.length}}<span ng-show="service.total > service.data.length"> of {{service.total}}</span>)
|
||||
|
@ -76,5 +76,5 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
</kbn-settings-objects>
|
||||
</kbn-settings-app>
|
||||
</kbn-management-objects>
|
||||
</kbn-management-app>
|
|
@ -1,8 +1,8 @@
|
|||
import { saveAs } from '@spalger/filesaver';
|
||||
import { extend, find, flattenDeep, partialRight, pick, pluck, sortBy } from 'lodash';
|
||||
import angular from 'angular';
|
||||
import registry from 'plugins/kibana/settings/saved_object_registry';
|
||||
import objectIndexHTML from 'plugins/kibana/settings/sections/objects/_objects.html';
|
||||
import registry from 'plugins/kibana/management/saved_object_registry';
|
||||
import objectIndexHTML from 'plugins/kibana/management/sections/objects/_objects.html';
|
||||
import 'ui/directives/file_upload';
|
||||
import uiRoutes from 'ui/routes';
|
||||
import uiModules from 'ui/modules';
|
||||
|
@ -10,12 +10,12 @@ import uiModules from 'ui/modules';
|
|||
const MAX_SIZE = Math.pow(2, 31) - 1;
|
||||
|
||||
uiRoutes
|
||||
.when('/settings/objects', {
|
||||
.when('/management/kibana/objects', {
|
||||
template: objectIndexHTML
|
||||
});
|
||||
|
||||
uiModules.get('apps/settings')
|
||||
.directive('kbnSettingsObjects', function (kbnIndex, Notifier, Private, kbnUrl, Promise) {
|
||||
uiModules.get('apps/management')
|
||||
.directive('kbnManagementObjects', function (kbnIndex, Notifier, Private, kbnUrl, Promise) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
controller: function ($scope, $injector, $q, AppState, es) {
|
||||
|
@ -79,13 +79,16 @@ uiModules.get('apps/settings')
|
|||
id: item.id
|
||||
};
|
||||
|
||||
kbnUrl.change('/settings/objects/{{ service }}/{{ id }}', params);
|
||||
kbnUrl.change('/management/kibana/objects/{{ service }}/{{ id }}', params);
|
||||
};
|
||||
|
||||
$scope.bulkDelete = function () {
|
||||
$scope.currentTab.service.delete(pluck($scope.selectedItems, 'id')).then(refreshData).then(function () {
|
||||
$scope.currentTab.service.delete(pluck($scope.selectedItems, 'id'))
|
||||
.then(refreshData)
|
||||
.then(function () {
|
||||
$scope.selectedItems.length = 0;
|
||||
});
|
||||
})
|
||||
.catch(error => notify.error(error));
|
||||
};
|
||||
|
||||
$scope.bulkExport = function () {
|
|
@ -1,5 +1,5 @@
|
|||
<kbn-settings-app section="objects">
|
||||
<kbn-settings-objects-view class="container">
|
||||
<kbn-management-app section="kibana">
|
||||
<kbn-management-objects-view class="container">
|
||||
<div class="pull-right" style="margin-top: 20px;">
|
||||
<a href="{{ link }}" class="btn btn-primary">View {{ title }}</a>
|
||||
<a confirm-click="delete()" class="btn btn-danger"><i class="fa fa-trash-o"></i> Delete {{ title }} Object</a>
|
||||
|
@ -32,5 +32,5 @@
|
|||
<button aria-label="Cancel" class="btn btn-primary" ng-click="cancel()">Cancel</button>
|
||||
<button aria-label="Save {{ title }} Object" class="btn btn-success" ng-click="submit()" ng-disabled="objectForm.$invalid || aceInvalidEditors.length !==0">Save {{ title }} Object</button>
|
||||
</div>
|
||||
</kbn-settings-objects-view>
|
||||
</kbn-settings-app>
|
||||
</kbn-management-objects-view>
|
||||
</kbn-management-app>
|
|
@ -1,19 +1,19 @@
|
|||
import _ from 'lodash';
|
||||
import angular from 'angular';
|
||||
import rison from 'rison-node';
|
||||
import registry from 'plugins/kibana/settings/saved_object_registry';
|
||||
import objectViewHTML from 'plugins/kibana/settings/sections/objects/_view.html';
|
||||
import registry from 'plugins/kibana/management/saved_object_registry';
|
||||
import objectViewHTML from 'plugins/kibana/management/sections/objects/_view.html';
|
||||
import IndexPatternsCastMappingTypeProvider from 'ui/index_patterns/_cast_mapping_type';
|
||||
import uiRoutes from 'ui/routes';
|
||||
import uiModules from 'ui/modules';
|
||||
|
||||
uiRoutes
|
||||
.when('/settings/objects/:service/:id', {
|
||||
.when('/management/kibana/objects/:service/:id', {
|
||||
template: objectViewHTML
|
||||
});
|
||||
|
||||
uiModules.get('apps/settings')
|
||||
.directive('kbnSettingsObjectsView', function (kbnIndex, Notifier) {
|
||||
uiModules.get('apps/management')
|
||||
.directive('kbnManagementObjectsView', function (kbnIndex, Notifier) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
controller: function ($scope, $injector, $routeParams, $location, $window, $rootScope, es, Private) {
|
||||
|
@ -210,7 +210,7 @@ uiModules.get('apps/settings')
|
|||
.then(function (resp) {
|
||||
const msg = 'You successfully ' + action + ' the "' + $scope.obj._source.title + '" ' + $scope.title.toLowerCase() + ' object';
|
||||
|
||||
$location.path('/settings/objects').search({
|
||||
$location.path('/management/kibana/objects').search({
|
||||
_a: rison.encode({
|
||||
tab: serviceObj.title
|
||||
})
|
|
@ -0,0 +1,15 @@
|
|||
import management from 'ui/management';
|
||||
import 'plugins/kibana/management/sections/objects/_view';
|
||||
import 'plugins/kibana/management/sections/objects/_objects';
|
||||
import 'ace';
|
||||
import 'ui/directives/confirm_click';
|
||||
import uiModules from 'ui/modules';
|
||||
|
||||
// add the module deps to this module
|
||||
uiModules.get('apps/management');
|
||||
|
||||
management.getSection('kibana').register('objects', {
|
||||
display: 'Saved Objects',
|
||||
order: 10,
|
||||
path: 'kibana/objects'
|
||||
});
|
|
@ -2,9 +2,9 @@ import _ from 'lodash';
|
|||
import 'ui/elastic_textarea';
|
||||
import 'ui/filters/markdown';
|
||||
import uiModules from 'ui/modules';
|
||||
import advancedRowTemplate from 'plugins/kibana/settings/sections/advanced/advanced_row.html';
|
||||
import advancedRowTemplate from 'plugins/kibana/management/sections/settings/advanced_row.html';
|
||||
|
||||
uiModules.get('apps/settings')
|
||||
uiModules.get('apps/management')
|
||||
.directive('advancedRow', function (config, Notifier) {
|
||||
return {
|
||||
restrict: 'A',
|
|
@ -1,5 +1,5 @@
|
|||
<kbn-settings-app section="advanced">
|
||||
<kbn-settings-advanced class="container">
|
||||
<kbn-management-app section="kibana">
|
||||
<kbn-management-advanced class="container-fluid">
|
||||
<div class="bs-callout bs-callout-warning">
|
||||
<h4>Caution: You can break stuff here</h4>
|
||||
Be careful in here, these settings are for very advanced users only.
|
||||
|
@ -24,5 +24,5 @@
|
|||
<tr ng-repeat="conf in configs | filter:advancedFilter" advanced-row="conf" configs="configs"></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</kbn-settings-advanced>
|
||||
</kbn-settings-app>
|
||||
</kbn-management-advanced>
|
||||
</kbn-management-app>
|
|
@ -1,18 +1,18 @@
|
|||
import _ from 'lodash';
|
||||
import registry from 'ui/registry/settings_sections';
|
||||
import toEditableConfig from 'plugins/kibana/settings/sections/advanced/lib/to_editable_config';
|
||||
import 'plugins/kibana/settings/sections/advanced/advanced_row';
|
||||
import toEditableConfig from 'plugins/kibana/management/sections/settings/lib/to_editable_config';
|
||||
import 'plugins/kibana/management/sections/settings/advanced_row';
|
||||
import management from 'ui/management';
|
||||
import uiRoutes from 'ui/routes';
|
||||
import uiModules from 'ui/modules';
|
||||
import indexTemplate from 'plugins/kibana/settings/sections/advanced/index.html';
|
||||
import indexTemplate from 'plugins/kibana/management/sections/settings/index.html';
|
||||
|
||||
uiRoutes
|
||||
.when('/settings/advanced', {
|
||||
.when('/management/kibana/settings', {
|
||||
template: indexTemplate
|
||||
});
|
||||
|
||||
uiModules.get('apps/settings')
|
||||
.directive('kbnSettingsAdvanced', function (config, Notifier, Private, $rootScope) {
|
||||
uiModules.get('apps/management')
|
||||
.directive('kbnManagementAdvanced', function (config, Notifier, Private, $rootScope) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function ($scope) {
|
||||
|
@ -39,9 +39,8 @@ uiModules.get('apps/settings')
|
|||
};
|
||||
});
|
||||
|
||||
registry.register(_.constant({
|
||||
order: 2,
|
||||
name: 'advanced',
|
||||
display: 'Advanced',
|
||||
url: '#/settings/advanced'
|
||||
}));
|
||||
management.getSection('kibana').register('settings', {
|
||||
display: 'Advanced Settings',
|
||||
order: 20,
|
||||
path: 'kibana/settings'
|
||||
});
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
import getEditorType from 'plugins/kibana/settings/sections/advanced/lib/get_editor_type';
|
||||
import getEditorType from 'plugins/kibana/management/sections/settings/lib/get_editor_type';
|
||||
import expect from 'expect.js';
|
||||
|
||||
describe('Settings', function () {
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
import getValType from 'plugins/kibana/settings/sections/advanced/lib/get_val_type';
|
||||
import getValType from 'plugins/kibana/management/sections/settings/lib/get_val_type';
|
||||
import expect from 'expect.js';
|
||||
|
||||
describe('Settings', function () {
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
import toEditableConfig from 'plugins/kibana/settings/sections/advanced/lib/to_editable_config';
|
||||
import toEditableConfig from 'plugins/kibana/management/sections/settings/lib/to_editable_config';
|
||||
import expect from 'expect.js';
|
||||
|
||||
describe('Settings', function () {
|
|
@ -1,13 +1,14 @@
|
|||
@import (reference) "~ui/styles/theme";
|
||||
@import (reference) "~ui/styles/variables";
|
||||
|
||||
kibana-settings-app,
|
||||
kbn-settings-indices,
|
||||
kbn-settings-indices-edit,
|
||||
kbn-settings-indices-create,
|
||||
kbn-settings-advanced,
|
||||
kbn-settings-objects,
|
||||
kbn-settings-objects-view {
|
||||
kbn-management-app,
|
||||
kbn-management-landing,
|
||||
kbn-management-indices,
|
||||
kbn-management-indices-edit,
|
||||
kbn-management-indices-create,
|
||||
kbn-management-advanced,
|
||||
kbn-management-objects,
|
||||
kbn-management-objects-view {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
@ -15,41 +16,110 @@ nav.navbar {
|
|||
height: 70px;
|
||||
}
|
||||
|
||||
.tab-management {
|
||||
background-color: @kibanaGray6;
|
||||
}
|
||||
|
||||
.settings-nav {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
li.kbn-settings-tab:first-letter {
|
||||
li.kbn-management-tab:first-letter {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
kbn-settings-app {
|
||||
div.app-container {
|
||||
div.container-fluid {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
kbn-management-app {
|
||||
bread-crumbs ul {
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
li.current-page {
|
||||
font-size: 1.5em;
|
||||
margin: 0 10px;
|
||||
}
|
||||
}
|
||||
|
||||
kbn-settings-objects {
|
||||
kbn-management-landing {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.management-panel-product {
|
||||
margin-bottom: 10px;
|
||||
|
||||
.panel-body {
|
||||
padding-bottom: 30px;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.management-section {
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.management-link {
|
||||
font-size: 17px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
.panel-heading-icon {
|
||||
font-size: 0.9em;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.product-overview {
|
||||
color: @kibanaGray2;
|
||||
padding: 5px 0 10px 10px;
|
||||
}
|
||||
|
||||
.management-section-info {
|
||||
bottom: 10px;
|
||||
display: none;
|
||||
color: @kibanaPink1;
|
||||
font-size: 0.8em;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.management-section-info-expanded {
|
||||
.panel-heading-icon {
|
||||
color: @black;
|
||||
}
|
||||
|
||||
.management-section-info {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
kbn-management-objects {
|
||||
form {
|
||||
margin-bottom: @line-height-computed;
|
||||
}
|
||||
.list-unstyled {
|
||||
li {
|
||||
border-bottom: 1px solid;
|
||||
border-bottom-color: @settings-objects-list-border;
|
||||
border-bottom-color: @management-objects-list-border;
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
.empty {
|
||||
color: @settings-objects-empty-color;
|
||||
color: @management-objects-empty-color;
|
||||
}
|
||||
|
||||
.item {
|
||||
padding: 12px;
|
||||
|
||||
.item-title {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
margin-top: -6px;
|
||||
}
|
||||
}
|
||||
|
||||
.action-bar {
|
||||
margin-top: 10px;
|
||||
background-color: @settings-objects-action-bar-bg;
|
||||
background-color: @management-objects-action-bar-bg;
|
||||
padding: 4px 12px;
|
||||
|
||||
label {
|
||||
|
@ -71,7 +141,7 @@ kbn-settings-objects {
|
|||
}
|
||||
}
|
||||
|
||||
kbn-settings-advanced {
|
||||
kbn-management-advanced {
|
||||
// super specific rule to override bootstrap's equally specific rule
|
||||
// https://github.com/twbs/bootstrap/blob/1f329f8f17aa989eabc6e94bdcab93e69ef0e463/less/tables.less#L35
|
||||
.table > tbody > tr > td {
|
||||
|
@ -79,32 +149,13 @@ kbn-settings-advanced {
|
|||
}
|
||||
}
|
||||
|
||||
kbn-settings-objects-view {
|
||||
kbn-management-objects-view {
|
||||
label {
|
||||
font-family: @font-family-monospace;
|
||||
}
|
||||
.ace_editor { height: 300px; }
|
||||
}
|
||||
|
||||
.kbn-settings-about {
|
||||
margin-top: 30px;
|
||||
|
||||
.jumbotron h1 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&-versions {
|
||||
td {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
td:first-child {
|
||||
font-weight: bold;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.advanced-settings {
|
||||
overflow-x: scroll;
|
||||
|
||||
|
@ -112,7 +163,7 @@ kbn-settings-objects-view {
|
|||
width: 100%;
|
||||
|
||||
tr.default td.value {
|
||||
color: @settings-advanced-table-default-color;
|
||||
color: @management-advanced-table-default-color;
|
||||
}
|
||||
|
||||
td {
|
||||
|
@ -125,23 +176,9 @@ kbn-settings-objects-view {
|
|||
}
|
||||
}
|
||||
|
||||
.objects-settings {
|
||||
.item {
|
||||
padding: 12px;
|
||||
|
||||
.item-title {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
margin-top: -6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.indices-settings {
|
||||
i.active {
|
||||
color: @settings-indices-active-color;
|
||||
color: @management-indices-active-color;
|
||||
}
|
||||
|
||||
tr.field-settings {
|
||||
|
@ -168,7 +205,7 @@ kbn-settings-objects-view {
|
|||
}
|
||||
}
|
||||
|
||||
kbn-settings-indices {
|
||||
kbn-management-indices {
|
||||
.fields {
|
||||
table {
|
||||
.table-striped()
|
||||
|
@ -197,7 +234,8 @@ kbn-settings-indices {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
.kbn-settings-indices-create {
|
||||
.time-and-pattern > div {}
|
||||
}
|
||||
|
||||
@import "~ui/dragula/gu-dragula.less";
|
|
@ -1,14 +0,0 @@
|
|||
<div class="app-container">
|
||||
<nav class="navbar navbar-default navbar-static-top subnav" data-test-subj="settingsNav">
|
||||
<div class="container-fluid">
|
||||
<bread-crumbs></bread-crumbs>
|
||||
<ul class="nav navbar-nav">
|
||||
<li ng-repeat="section in sections" ng-class="section.class">
|
||||
<a class="navbar-link" kbn-href="{{section.url}}" data-test-subj="{{section.name}}">{{section.display}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div role="main" class="settings-section-container {{section.name}}-settings" ng-transclude></div>
|
||||
</div>
|
|
@ -1,53 +0,0 @@
|
|||
import _ from 'lodash';
|
||||
import 'plugins/kibana/settings/sections/indices/index';
|
||||
import 'plugins/kibana/settings/sections/advanced/index';
|
||||
import 'plugins/kibana/settings/sections/objects/index';
|
||||
import 'plugins/kibana/settings/sections/status/index';
|
||||
import 'plugins/kibana/settings/sections/about/index';
|
||||
import 'plugins/kibana/settings/styles/main.less';
|
||||
import 'ui/filters/start_from';
|
||||
import 'ui/field_editor';
|
||||
import 'plugins/kibana/settings/sections/indices/_indexed_fields';
|
||||
import 'plugins/kibana/settings/sections/indices/_scripted_fields';
|
||||
import 'ui/directives/bread_crumbs';
|
||||
import registry from 'ui/registry/settings_sections';
|
||||
import uiRoutes from 'ui/routes';
|
||||
import uiModules from 'ui/modules';
|
||||
import appTemplate from 'plugins/kibana/settings/app.html';
|
||||
|
||||
|
||||
uiRoutes
|
||||
.when('/settings', {
|
||||
redirectTo: '/settings/indices'
|
||||
});
|
||||
|
||||
require('ui/index_patterns/route_setup/load_default')({
|
||||
notRequiredRe: /^\/settings\//,
|
||||
whenMissingRedirectTo: '/settings/indices'
|
||||
});
|
||||
|
||||
uiModules
|
||||
.get('apps/settings')
|
||||
.directive('kbnSettingsApp', function (Private, $route, timefilter) {
|
||||
const sections = Private(registry);
|
||||
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: appTemplate,
|
||||
transclude: true,
|
||||
scope: {
|
||||
sectionName: '@section'
|
||||
},
|
||||
link: function ($scope, $el) {
|
||||
timefilter.enabled = false;
|
||||
$scope.sections = sections.inOrder;
|
||||
$scope.section = _.find($scope.sections, { name: $scope.sectionName });
|
||||
|
||||
$scope.sections.forEach(section => {
|
||||
section.class = section === $scope.section ? 'active' : undefined;
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// preload
|
|
@ -1,454 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64"
|
||||
height="64"
|
||||
id="svg5235"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
viewBox="0 0 64 64"
|
||||
sodipodi:docname="barcode.svg">
|
||||
<defs
|
||||
id="defs5237" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.5"
|
||||
inkscape:cx="4.3636364"
|
||||
inkscape:cy="32"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="2880"
|
||||
inkscape:window-height="1140"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="23"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata5240">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<g
|
||||
id="g4300"
|
||||
transform="matrix(1.1002186,0,0,1.1002186,-3.2119331,-3.0092752)">
|
||||
<g
|
||||
transform="matrix(0.57440105,0,0,0.57440105,-36.987859,-56.970747)"
|
||||
id="g6209">
|
||||
<rect
|
||||
style="opacity:1;fill:#39bdb1;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-3"
|
||||
width="2.4159346"
|
||||
height="100.54836"
|
||||
x="97.825981"
|
||||
y="104.33428" />
|
||||
<rect
|
||||
style="opacity:1;fill:#ea458b;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-9"
|
||||
width="7.5297971"
|
||||
height="100.54836"
|
||||
x="85.735123"
|
||||
y="104.33428" />
|
||||
<rect
|
||||
style="opacity:1;fill:#f3bb19;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-8"
|
||||
width="5.0022545"
|
||||
height="100.54836"
|
||||
x="75.889793"
|
||||
y="104.33428" />
|
||||
<rect
|
||||
style="opacity:1;fill:#2d448e;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-2"
|
||||
width="3.2287681"
|
||||
height="100.54836"
|
||||
x="72.783882"
|
||||
y="104.33428" />
|
||||
<rect
|
||||
style="opacity:1;fill:#83cb1c;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251"
|
||||
width="3.159905"
|
||||
height="100.54836"
|
||||
x="69.63768"
|
||||
y="104.33428" />
|
||||
<rect
|
||||
style="opacity:1;fill:#ea458b;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-9-9"
|
||||
width="6.9419966"
|
||||
height="100.54836"
|
||||
x="119.37186"
|
||||
y="104.33428" />
|
||||
<rect
|
||||
style="opacity:1;fill:#006555;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-5-9"
|
||||
width="4.9434743"
|
||||
height="100.54836"
|
||||
x="131.24544"
|
||||
y="104.33428" />
|
||||
<rect
|
||||
style="opacity:1;fill:#006555;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-5-0"
|
||||
width="1.8869137"
|
||||
height="100.54836"
|
||||
x="83.986267"
|
||||
y="104.33428" />
|
||||
<rect
|
||||
style="opacity:1;fill:#83cb1c;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-7"
|
||||
width="4.7083545"
|
||||
height="100.54836"
|
||||
x="93.214729"
|
||||
y="104.33428" />
|
||||
<rect
|
||||
style="opacity:1;fill:#83cb1c;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-36"
|
||||
width="5.8251753"
|
||||
height="100.54836"
|
||||
x="136.24173"
|
||||
y="104.33428" />
|
||||
<rect
|
||||
style="opacity:1;fill:#39bdb1;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-3-7"
|
||||
width="3.1212945"
|
||||
height="100.54836"
|
||||
x="80.870918"
|
||||
y="104.33428" />
|
||||
<rect
|
||||
style="opacity:1;fill:#ea458b;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-9-9-3"
|
||||
width="3.5915353"
|
||||
height="100.54836"
|
||||
x="100.15076"
|
||||
y="104.33428" />
|
||||
<rect
|
||||
style="opacity:1;fill:#ea458b;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-9-9-8"
|
||||
width="3.9442151"
|
||||
height="100.54836"
|
||||
x="166.68982"
|
||||
y="104.33428" />
|
||||
<rect
|
||||
style="opacity:1;fill:#39bdb1;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-3-3"
|
||||
width="3.3564136"
|
||||
height="100.54836"
|
||||
x="110.55486"
|
||||
y="104.33428" />
|
||||
<rect
|
||||
style="opacity:1;fill:#39bdb1;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-3-0"
|
||||
width="4.1793332"
|
||||
height="100.54836"
|
||||
x="148.82066"
|
||||
y="104.33429" />
|
||||
<rect
|
||||
style="opacity:1;fill:#f3bb19;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-8-3"
|
||||
width="2.1808138"
|
||||
height="100.54838"
|
||||
x="129.07057"
|
||||
y="104.33427" />
|
||||
<rect
|
||||
style="opacity:1;fill:#f3bb19;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-8-33"
|
||||
width="3.0037344"
|
||||
height="100.54836"
|
||||
x="142.00218"
|
||||
y="104.33428" />
|
||||
<rect
|
||||
style="opacity:1;fill:#83cb1c;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-7-3"
|
||||
width="4.3556747"
|
||||
height="100.54836"
|
||||
x="106.20512"
|
||||
y="104.33428" />
|
||||
<rect
|
||||
style="opacity:1;fill:#2d448e;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-2-0"
|
||||
width="2.4159336"
|
||||
height="100.54836"
|
||||
x="103.73636"
|
||||
y="104.33428" />
|
||||
<rect
|
||||
style="opacity:1;fill:#83cb1c;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-36-7"
|
||||
width="3.8266549"
|
||||
height="100.54836"
|
||||
x="116.25652"
|
||||
y="104.33428" />
|
||||
<rect
|
||||
style="opacity:1;fill:#006555;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-5-3"
|
||||
width="2.2983737"
|
||||
height="100.54838"
|
||||
x="113.9641"
|
||||
y="104.33427" />
|
||||
<rect
|
||||
style="opacity:1;fill:#39bdb1;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-3-7-7"
|
||||
width="2.8273947"
|
||||
height="100.54836"
|
||||
x="126.30791"
|
||||
y="104.33428" />
|
||||
<rect
|
||||
style="opacity:1;fill:#39bdb1;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-3-7-70"
|
||||
width="2.0632553"
|
||||
height="100.54836"
|
||||
x="144.8824"
|
||||
y="104.33428" />
|
||||
<rect
|
||||
style="opacity:1;fill:#ea458b;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-9-9-8-4"
|
||||
width="1.8869162"
|
||||
height="100.54836"
|
||||
x="146.99847"
|
||||
y="104.33428" />
|
||||
<rect
|
||||
style="opacity:1;fill:#39bdb1;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-3-7-70-2"
|
||||
width="4.708354"
|
||||
height="100.54836"
|
||||
x="158.32114"
|
||||
y="104.33428" />
|
||||
<rect
|
||||
style="opacity:1;fill:#f3bb19;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-8-339-2"
|
||||
width="5.413713"
|
||||
height="100.54838"
|
||||
x="152.97215"
|
||||
y="104.33427" />
|
||||
<rect
|
||||
style="opacity:1;fill:#83cb1c;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5251-36-5"
|
||||
width="3.8266544"
|
||||
height="100.54836"
|
||||
x="162.99417"
|
||||
y="104.33428" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.57440105,0,0,1.9251702,3.0622581,2.9589583)"
|
||||
id="g4544">
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:2"
|
||||
x1="1"
|
||||
y1="0"
|
||||
x2="1"
|
||||
y2="30"
|
||||
id="line4450" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:1"
|
||||
x1="3.5"
|
||||
y1="0"
|
||||
x2="3.5"
|
||||
y2="30"
|
||||
id="line4452" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:1"
|
||||
x1="6.5"
|
||||
y1="0"
|
||||
x2="6.5"
|
||||
y2="30"
|
||||
id="line4454" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:1"
|
||||
x1="11.5"
|
||||
y1="0"
|
||||
x2="11.5"
|
||||
y2="30"
|
||||
id="line4456" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:1"
|
||||
x1="14.5"
|
||||
y1="0"
|
||||
x2="14.5"
|
||||
y2="30"
|
||||
id="line4458" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:2"
|
||||
x1="17"
|
||||
y1="0"
|
||||
x2="17"
|
||||
y2="30"
|
||||
id="line4460" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:2"
|
||||
x1="23"
|
||||
y1="0"
|
||||
x2="23"
|
||||
y2="30"
|
||||
id="line4462" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:1"
|
||||
x1="28.5"
|
||||
y1="0"
|
||||
x2="28.5"
|
||||
y2="30"
|
||||
id="line4464" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:1"
|
||||
x1="30.5"
|
||||
y1="0"
|
||||
x2="30.5"
|
||||
y2="30"
|
||||
id="line4466" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:2"
|
||||
x1="34"
|
||||
y1="0"
|
||||
x2="34"
|
||||
y2="30"
|
||||
id="line4468" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:2"
|
||||
x1="37"
|
||||
y1="0"
|
||||
x2="37"
|
||||
y2="30"
|
||||
id="line4470" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:2"
|
||||
x1="41"
|
||||
y1="0"
|
||||
x2="41"
|
||||
y2="30"
|
||||
id="line4472" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:1"
|
||||
x1="44.5"
|
||||
y1="0"
|
||||
x2="44.5"
|
||||
y2="30"
|
||||
id="line4474" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:2"
|
||||
x1="47"
|
||||
y1="0"
|
||||
x2="47"
|
||||
y2="30"
|
||||
id="line4476" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:1"
|
||||
x1="50.5"
|
||||
y1="0"
|
||||
x2="50.5"
|
||||
y2="30"
|
||||
id="line4478" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:2"
|
||||
x1="56"
|
||||
y1="0"
|
||||
x2="56"
|
||||
y2="30"
|
||||
id="line4480" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:1"
|
||||
x1="59.5"
|
||||
y1="0"
|
||||
x2="59.5"
|
||||
y2="30"
|
||||
id="line4482" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:1"
|
||||
x1="61.5"
|
||||
y1="0"
|
||||
x2="61.5"
|
||||
y2="30"
|
||||
id="line4484" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:2"
|
||||
x1="67"
|
||||
y1="0"
|
||||
x2="67"
|
||||
y2="30"
|
||||
id="line4486" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:1"
|
||||
x1="72.5"
|
||||
y1="0"
|
||||
x2="72.5"
|
||||
y2="30"
|
||||
id="line4488" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:1"
|
||||
x1="75.5"
|
||||
y1="0"
|
||||
x2="75.5"
|
||||
y2="30"
|
||||
id="line4490" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:1"
|
||||
x1="77.5"
|
||||
y1="0"
|
||||
x2="77.5"
|
||||
y2="30"
|
||||
id="line4492" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:1"
|
||||
x1="79.5"
|
||||
y1="0"
|
||||
x2="79.5"
|
||||
y2="30"
|
||||
id="line4494" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:4"
|
||||
x1="83"
|
||||
y1="0"
|
||||
x2="83"
|
||||
y2="30"
|
||||
id="line4496" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:2"
|
||||
x1="89"
|
||||
y1="0"
|
||||
x2="89"
|
||||
y2="30"
|
||||
id="line4498" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:3"
|
||||
x1="94.5"
|
||||
y1="0"
|
||||
x2="94.5"
|
||||
y2="30"
|
||||
id="line4500" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:1"
|
||||
x1="97.5"
|
||||
y1="0"
|
||||
x2="97.5"
|
||||
y2="30"
|
||||
id="line4502" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:2"
|
||||
x1="100"
|
||||
y1="0"
|
||||
x2="100"
|
||||
y2="30"
|
||||
id="line4504" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 16 KiB |
|
@ -1,35 +0,0 @@
|
|||
<kbn-settings-app section="about">
|
||||
<div class="kbn-settings-about container" ng-controller="settingsAbout">
|
||||
<div class="col-md-4 col-md-offset-4 jumbotron">
|
||||
<center>
|
||||
<img kbn-src="/plugins/kibana/settings/sections/about/barcode.svg" alt="Kibana Barcode Logo" width="128" height="128"><br>
|
||||
<h1>Kibana</h1>
|
||||
<p>
|
||||
<table class="table table-condensed kbn-settings-about-versions">
|
||||
<tr>
|
||||
<td>Version</td>
|
||||
<td>{{kbnVersion}}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Build</td>
|
||||
<td>{{buildNum}}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Commit SHA</td>
|
||||
<td>{{buildSha | limitTo:7}}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Server name</td>
|
||||
<td>{{serverName}}</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</p>
|
||||
<small>© 2015 All Rights Reserved - <a href="https://elastic.co">Elasticsearch</a></small>
|
||||
</center>
|
||||
</div>
|
||||
</div>
|
||||
</kbn-settings-app>
|
|
@ -1,25 +0,0 @@
|
|||
import _ from 'lodash';
|
||||
import registry from 'ui/registry/settings_sections';
|
||||
import uiRoutes from 'ui/routes';
|
||||
import uiModules from 'ui/modules';
|
||||
import indexTemplate from 'plugins/kibana/settings/sections/about/index.html';
|
||||
|
||||
uiRoutes
|
||||
.when('/settings/about', {
|
||||
template: indexTemplate
|
||||
});
|
||||
|
||||
uiModules.get('apps/settings')
|
||||
.controller('settingsAbout', function ($scope, kbnVersion, buildNum, buildSha, serverName) {
|
||||
$scope.kbnVersion = kbnVersion;
|
||||
$scope.buildNum = buildNum;
|
||||
$scope.buildSha = buildSha;
|
||||
$scope.serverName = serverName;
|
||||
});
|
||||
|
||||
registry.register(_.constant({
|
||||
order: 1001,
|
||||
name: 'about',
|
||||
display: 'About',
|
||||
url: '#/settings/about'
|
||||
}));
|
|
@ -1,54 +0,0 @@
|
|||
import _ from 'lodash';
|
||||
import registry from 'ui/registry/settings_sections';
|
||||
import 'plugins/kibana/settings/sections/indices/_create';
|
||||
import 'plugins/kibana/settings/sections/indices/_edit';
|
||||
import 'plugins/kibana/settings/sections/indices/_field_editor';
|
||||
import uiRoutes from 'ui/routes';
|
||||
import uiModules from 'ui/modules';
|
||||
import indexTemplate from 'plugins/kibana/settings/sections/indices/index.html';
|
||||
|
||||
|
||||
// add a dependency to all of the subsection routes
|
||||
uiRoutes
|
||||
.defaults(/settings\/indices/, {
|
||||
resolve: {
|
||||
indexPatternIds: function (courier) {
|
||||
return courier.indexPatterns.getIds();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// wrapper directive, which sets some global stuff up like the left nav
|
||||
uiModules.get('apps/settings')
|
||||
.directive('kbnSettingsIndices', function ($route, config, kbnUrl) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
transclude: true,
|
||||
template: indexTemplate,
|
||||
link: function ($scope) {
|
||||
$scope.editingId = $route.current.params.indexPatternId;
|
||||
config.bindToScope($scope, 'defaultIndex');
|
||||
|
||||
$scope.$watch('defaultIndex', function () {
|
||||
const ids = $route.current.locals.indexPatternIds;
|
||||
$scope.indexPatternList = ids.map(function (id) {
|
||||
return {
|
||||
id: id,
|
||||
url: kbnUrl.eval('#/settings/indices/{{id}}', {id: id}),
|
||||
class: 'sidebar-item-title ' + ($scope.editingId === id ? 'active' : ''),
|
||||
default: $scope.defaultIndex === id
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
$scope.$emit('application.load');
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
registry.register(_.constant({
|
||||
order: 1,
|
||||
name: 'indices',
|
||||
display: 'Indices',
|
||||
url: '#/settings/indices'
|
||||
}));
|
|
@ -1,18 +0,0 @@
|
|||
import _ from 'lodash';
|
||||
import registry from 'ui/registry/settings_sections';
|
||||
import 'plugins/kibana/settings/sections/objects/_view';
|
||||
import 'plugins/kibana/settings/sections/objects/_objects';
|
||||
import 'ace';
|
||||
import 'ui/directives/confirm_click';
|
||||
import uiModules from 'ui/modules';
|
||||
|
||||
|
||||
// add the module deps to this module
|
||||
uiModules.get('apps/settings');
|
||||
|
||||
registry.register(_.constant({
|
||||
order: 3,
|
||||
name: 'objects',
|
||||
display: 'Objects',
|
||||
url: '#/settings/objects'
|
||||
}));
|
|
@ -1,9 +0,0 @@
|
|||
import _ from 'lodash';
|
||||
import registry from 'ui/registry/settings_sections';
|
||||
|
||||
registry.register(_.constant({
|
||||
order: 1000,
|
||||
name: 'status',
|
||||
display: 'Status',
|
||||
url: '/status'
|
||||
}));
|
|
@ -0,0 +1,121 @@
|
|||
import angular from 'angular';
|
||||
import sinon from 'sinon';
|
||||
import expect from 'expect.js';
|
||||
import ngMock from 'ng_mock';
|
||||
|
||||
let init;
|
||||
let $rootScope;
|
||||
let $compile;
|
||||
|
||||
describe('draggable_* directives', function () {
|
||||
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(ngMock.inject(function ($injector) {
|
||||
$rootScope = $injector.get('$rootScope');
|
||||
$compile = $injector.get('$compile');
|
||||
init = function init(markup = '') {
|
||||
const $parentScope = $rootScope.$new();
|
||||
$parentScope.items = [
|
||||
{ name: 'item_1' },
|
||||
{ name: 'item_2' },
|
||||
{ name: 'item_3' }
|
||||
];
|
||||
|
||||
// create the markup
|
||||
const $elem = angular.element(`<div draggable-container="items">`);
|
||||
$elem.html(markup);
|
||||
|
||||
// compile the directive
|
||||
$compile($elem)($parentScope);
|
||||
$parentScope.$apply();
|
||||
|
||||
const $scope = $elem.scope();
|
||||
|
||||
return { $parentScope, $scope, $elem };
|
||||
};
|
||||
}));
|
||||
|
||||
describe('draggable_container directive', function () {
|
||||
it('should expose the drake', function () {
|
||||
const { $scope } = init();
|
||||
expect($scope.drake).to.be.an(Object);
|
||||
});
|
||||
|
||||
it('should expose the controller', function () {
|
||||
const { $scope } = init();
|
||||
expect($scope.draggableContainerCtrl).to.be.an(Object);
|
||||
});
|
||||
|
||||
it('should pull item list from directive attribute', function () {
|
||||
const { $scope, $parentScope } = init();
|
||||
expect($scope.draggableContainerCtrl.getList()).to.eql($parentScope.items);
|
||||
});
|
||||
|
||||
it('should not be able to move extraneous DOM elements', function () {
|
||||
const bare = angular.element(`<div>`);
|
||||
const { $scope } = init();
|
||||
expect($scope.drake.canMove(bare[0])).to.eql(false);
|
||||
});
|
||||
|
||||
it('should not be able to move non-[draggable-item] elements', function () {
|
||||
const bare = angular.element(`<div>`);
|
||||
const { $scope, $elem } = init();
|
||||
$elem.append(bare);
|
||||
expect($scope.drake.canMove(bare[0])).to.eql(false);
|
||||
});
|
||||
|
||||
it('shouldn\'t be able to move extraneous [draggable-item] elements', function () {
|
||||
const anotherParent = angular.element(`<div draggable-container="items">`);
|
||||
const item = angular.element(`<div draggable-item="items[0]">`);
|
||||
const scope = $rootScope.$new();
|
||||
anotherParent.append(item);
|
||||
$compile(anotherParent)(scope);
|
||||
$compile(item)(scope);
|
||||
scope.$apply();
|
||||
const { $scope } = init();
|
||||
expect($scope.drake.canMove(item[0])).to.eql(false);
|
||||
});
|
||||
|
||||
it('shouldn\'t be able to move [draggable-item] if it has a handle', function () {
|
||||
const { $scope, $elem } = init(`
|
||||
<div draggable-item="items[0]">
|
||||
<div draggable-handle></div>
|
||||
</div>
|
||||
`);
|
||||
const item = $elem.find(`[draggable-item]`);
|
||||
expect($scope.drake.canMove(item[0])).to.eql(false);
|
||||
});
|
||||
|
||||
it('should be able to move [draggable-item] by its handle', function () {
|
||||
const { $scope, $elem } = init(`
|
||||
<div draggable-item="items[0]">
|
||||
<div draggable-handle></div>
|
||||
</div>
|
||||
`);
|
||||
const handle = $elem.find(`[draggable-handle]`);
|
||||
expect($scope.drake.canMove(handle[0])).to.eql(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('draggable_item', function () {
|
||||
it('should be required to be a child to [draggable-container]', function () {
|
||||
const item = angular.element(`<div draggable-item="items[0]">`);
|
||||
const scope = $rootScope.$new();
|
||||
expect(() => {
|
||||
$compile(item)(scope);
|
||||
scope.$apply();
|
||||
}).to.throwException(/controller(.+)draggableContainer(.+)required/i);
|
||||
});
|
||||
});
|
||||
|
||||
describe('draggable_handle', function () {
|
||||
it('should be required to be a child to [draggable-item]', function () {
|
||||
const handle = angular.element(`<div draggable-handle>`);
|
||||
const scope = $rootScope.$new();
|
||||
expect(() => {
|
||||
$compile(handle)(scope);
|
||||
scope.$apply();
|
||||
}).to.throwException(/controller(.+)draggableItem(.+)required/i);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -27,30 +27,40 @@
|
|||
|
||||
<!-- controls !!!actually disabling buttons will break tooltips¡¡¡ -->
|
||||
<div class="vis-editor-agg-header-controls btn-group">
|
||||
<!-- up button -->
|
||||
<!-- disable aggregation -->
|
||||
<button
|
||||
aria-label="Increase Priority"
|
||||
ng-if="stats.count > 1"
|
||||
ng-class="{ disabled: $first }"
|
||||
ng-click="moveUp(agg)"
|
||||
tooltip="Increase Priority"
|
||||
ng-if="agg.enabled && canRemove(agg)"
|
||||
ng-click="agg.enabled = false"
|
||||
aria-label="Disable aggregation"
|
||||
tooltip="Disable aggregation"
|
||||
tooltip-append-to-body="true"
|
||||
type="button"
|
||||
class="btn btn-xs btn-primary">
|
||||
<i aria-hidden="true" class="fa fa-caret-up"></i>
|
||||
class="btn btn-xs">
|
||||
<i aria-hidden="true" class="fa fa-toggle-on"></i>
|
||||
</button>
|
||||
|
||||
<!-- down button -->
|
||||
<!-- enable aggregation -->
|
||||
<button
|
||||
aria-label="Decrease Priority"
|
||||
ng-if="stats.count > 1"
|
||||
ng-class="{ disabled: $last }"
|
||||
ng-click="moveDown(agg)"
|
||||
tooltip="Decrease Priority"
|
||||
ng-if="!agg.enabled"
|
||||
ng-click="agg.enabled = true"
|
||||
aria-label="Enable aggregation"
|
||||
tooltip="Enable aggregation"
|
||||
tooltip-append-to-body="true"
|
||||
type="button"
|
||||
class="btn btn-xs btn-primary">
|
||||
<i aria-hidden="true" class="fa fa-caret-down"></i>
|
||||
class="btn btn-xs">
|
||||
<i aria-hidden="true" class="fa fa-toggle-off"></i>
|
||||
</button>
|
||||
|
||||
<!-- drag handle -->
|
||||
<button
|
||||
draggable-handle
|
||||
aria-label="Modify Priority by Dragging"
|
||||
ng-if="stats.count > 1"
|
||||
tooltip="Modify Priority by Dragging"
|
||||
tooltip-append-to-body="true"
|
||||
type="button"
|
||||
class="btn btn-xs">
|
||||
<i aria-hidden="true" class="fa fa-arrows-v"></i>
|
||||
</button>
|
||||
|
||||
<!-- remove button -->
|
||||
|
@ -79,5 +89,6 @@
|
|||
|
||||
<vis-editor-agg-add
|
||||
ng-if="$index + 1 === stats.count"
|
||||
ng-hide="dragging"
|
||||
class="vis-editor-agg-add vis-editor-agg-add-subagg">
|
||||
</vis-editor-agg-add>
|
||||
|
|
|
@ -21,7 +21,6 @@ uiModules
|
|||
template: aggTemplate,
|
||||
require: 'form',
|
||||
link: function ($scope, $el, attrs, kbnForm) {
|
||||
$scope.$bind('outputAgg', 'outputVis.aggs.byId[agg.id]', $scope);
|
||||
$scope.editorOpen = !!$scope.agg.brandNew;
|
||||
|
||||
$scope.$watch('editorOpen', function (open) {
|
||||
|
@ -47,13 +46,16 @@ uiModules
|
|||
return label ? label : '';
|
||||
};
|
||||
|
||||
function move(below, agg) {
|
||||
_.move($scope.vis.aggs, agg, below, function (otherAgg) {
|
||||
return otherAgg.schema.group === agg.schema.group;
|
||||
});
|
||||
}
|
||||
$scope.moveUp = _.partial(move, false);
|
||||
$scope.moveDown = _.partial(move, true);
|
||||
$scope.$on('drag-start', e => {
|
||||
$scope.editorWasOpen = $scope.editorOpen;
|
||||
$scope.editorOpen = false;
|
||||
$scope.$emit('agg-drag-start', $scope.agg);
|
||||
});
|
||||
|
||||
$scope.$on('drag-end', e => {
|
||||
$scope.editorOpen = $scope.editorWasOpen;
|
||||
$scope.$emit('agg-drag-end', $scope.agg);
|
||||
});
|
||||
|
||||
$scope.remove = function (agg) {
|
||||
const aggs = $scope.vis.aggs;
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
{{ groupName }}
|
||||
</div>
|
||||
|
||||
<div class="vis-editor-agg-group" ng-class="groupName">
|
||||
<div ng-class="groupName" draggable-container="vis.aggs" class="vis-editor-agg-group">
|
||||
<!-- wrapper needed for nesting-indicator -->
|
||||
<div ng-repeat="agg in group" class="vis-editor-agg-wrapper">
|
||||
<div ng-repeat="agg in group" draggable-item="agg" class="vis-editor-agg-wrapper">
|
||||
<!-- agg.html - controls for aggregation -->
|
||||
<ng-form vis-editor-agg name="aggForm" class="vis-editor-agg"></ng-form>
|
||||
</div>
|
||||
|
|
|
@ -41,6 +41,9 @@ uiModules
|
|||
if (count < schema.max) return true;
|
||||
});
|
||||
});
|
||||
|
||||
$scope.$on('agg-drag-start', e => $scope.dragging = true);
|
||||
$scope.$on('agg-drag-end', e => $scope.dragging = false);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
import _ from 'lodash';
|
||||
import $ from 'jquery';
|
||||
import dragula from 'dragula';
|
||||
import uiModules from 'ui/modules';
|
||||
|
||||
uiModules
|
||||
.get('app/visualize')
|
||||
.directive('draggableContainer', function () {
|
||||
|
||||
return {
|
||||
restrict: 'A',
|
||||
scope: true,
|
||||
controllerAs: 'draggableContainerCtrl',
|
||||
controller($scope, $attrs, $parse) {
|
||||
this.getList = () => $parse($attrs.draggableContainer)($scope);
|
||||
},
|
||||
link($scope, $el, attr) {
|
||||
const drake = dragula({
|
||||
containers: $el.toArray(),
|
||||
moves(el, source, handle) {
|
||||
const itemScope = $(el).scope();
|
||||
if (!('draggableItemCtrl' in itemScope)) {
|
||||
return; // only [draggable-item] is draggable
|
||||
}
|
||||
return itemScope.draggableItemCtrl.moves(handle);
|
||||
}
|
||||
});
|
||||
|
||||
const drakeEvents = [
|
||||
'cancel',
|
||||
'cloned',
|
||||
'drag',
|
||||
'dragend',
|
||||
'drop',
|
||||
'out',
|
||||
'over',
|
||||
'remove',
|
||||
'shadow'
|
||||
];
|
||||
const prettifiedDrakeEvents = {
|
||||
drag: 'start',
|
||||
dragend: 'end'
|
||||
};
|
||||
|
||||
drakeEvents.forEach(type => {
|
||||
drake.on(type, (el, ...args) => forwardEvent(type, el, ...args));
|
||||
});
|
||||
drake.on('drag', markDragging(true));
|
||||
drake.on('dragend', markDragging(false));
|
||||
drake.on('drop', drop);
|
||||
$scope.$on('$destroy', drake.destroy);
|
||||
$scope.drake = drake;
|
||||
|
||||
function markDragging(isDragging) {
|
||||
return el => {
|
||||
const scope = $(el).scope();
|
||||
scope.isDragging = isDragging;
|
||||
scope.$apply();
|
||||
};
|
||||
}
|
||||
|
||||
function forwardEvent(type, el, ...args) {
|
||||
const name = `drag-${prettifiedDrakeEvents[type] || type}`;
|
||||
const scope = $(el).scope();
|
||||
scope.$broadcast(name, el, ...args);
|
||||
}
|
||||
|
||||
function drop(el, target, source, sibling) {
|
||||
const list = $scope.draggableContainerCtrl.getList();
|
||||
const itemScope = $(el).scope();
|
||||
const item = itemScope.draggableItemCtrl.getItem();
|
||||
const toIndex = getSiblingItemIndex(list, sibling);
|
||||
_.move(list, item, toIndex);
|
||||
}
|
||||
|
||||
function getSiblingItemIndex(list, sibling) {
|
||||
if (!sibling) { // means the item was dropped at the end of the list
|
||||
return list.length - 1;
|
||||
}
|
||||
const siblingScope = $(sibling).scope();
|
||||
const siblingItem = siblingScope.draggableItemCtrl.getItem();
|
||||
const siblingIndex = list.indexOf(siblingItem);
|
||||
return siblingIndex;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
});
|
|
@ -0,0 +1,14 @@
|
|||
import uiModules from 'ui/modules';
|
||||
|
||||
uiModules
|
||||
.get('app/visualize')
|
||||
.directive('draggableHandle', function () {
|
||||
return {
|
||||
restrict: 'A',
|
||||
require: '^draggableItem',
|
||||
link($scope, $el, attr, ctrl) {
|
||||
ctrl.registerHandle($el);
|
||||
$el.addClass('gu-handle');
|
||||
}
|
||||
};
|
||||
});
|
29
src/plugins/kibana/public/visualize/editor/draggable_item.js
Normal file
29
src/plugins/kibana/public/visualize/editor/draggable_item.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
import $ from 'jquery';
|
||||
import uiModules from 'ui/modules';
|
||||
|
||||
uiModules
|
||||
.get('app/visualize')
|
||||
.directive('draggableItem', function () {
|
||||
return {
|
||||
restrict: 'A',
|
||||
require: '^draggableContainer',
|
||||
scope: true,
|
||||
controllerAs: 'draggableItemCtrl',
|
||||
controller($scope, $attrs, $parse) {
|
||||
const dragHandles = $();
|
||||
|
||||
this.getItem = () => $parse($attrs.draggableItem)($scope);
|
||||
this.registerHandle = $el => {
|
||||
dragHandles.push(...$el);
|
||||
};
|
||||
this.moves = handle => {
|
||||
const $handle = $(handle);
|
||||
const $anywhereInParentChain = $handle.parents().addBack();
|
||||
const movable = dragHandles.is($anywhereInParentChain);
|
||||
return movable;
|
||||
};
|
||||
},
|
||||
link($scope, $el, attr) {
|
||||
}
|
||||
};
|
||||
});
|
|
@ -43,9 +43,9 @@ uiRoutes
|
|||
return savedVisualizations.get($route.current.params.id)
|
||||
.catch(courier.redirectWhenMissing({
|
||||
'visualization': '/visualize',
|
||||
'search': '/settings/objects/savedVisualizations/' + $route.current.params.id,
|
||||
'index-pattern': '/settings/objects/savedVisualizations/' + $route.current.params.id,
|
||||
'index-pattern-field': '/settings/objects/savedVisualizations/' + $route.current.params.id
|
||||
'search': '/management/kibana/objects/savedVisualizations/' + $route.current.params.id,
|
||||
'index-pattern': '/management/kibana/objects/savedVisualizations/' + $route.current.params.id,
|
||||
'index-pattern-field': '/management/kibana/objects/savedVisualizations/' + $route.current.params.id
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
@ -119,8 +119,8 @@ uiModules
|
|||
|
||||
if (!angular.equals($state.vis, savedVisState)) {
|
||||
Promise.try(function () {
|
||||
vis.setState($state.vis);
|
||||
editableVis.setState($state.vis);
|
||||
vis.setState(editableVis.getEnabledState());
|
||||
})
|
||||
.catch(courier.redirectWhenMissing({
|
||||
'index-pattern-field': '/visualize'
|
||||
|
@ -139,6 +139,7 @@ uiModules
|
|||
$scope.editableVis = editableVis;
|
||||
$scope.state = $state;
|
||||
$scope.uiState = $state.makeStateful('uiState');
|
||||
vis.setUiState($scope.uiState);
|
||||
$scope.timefilter = timefilter;
|
||||
$scope.opts = _.pick($scope, 'doSave', 'savedVis', 'shareData', 'timefilter');
|
||||
|
||||
|
@ -149,9 +150,9 @@ uiModules
|
|||
$scope.stageEditableVis = transferVisState(editableVis, vis, true);
|
||||
$scope.resetEditableVis = transferVisState(vis, editableVis);
|
||||
$scope.$watch(function () {
|
||||
return editableVis.getState();
|
||||
return editableVis.getEnabledState();
|
||||
}, function (newState) {
|
||||
editableVis.dirty = !angular.equals(newState, vis.getState());
|
||||
editableVis.dirty = !angular.equals(newState, vis.getEnabledState());
|
||||
|
||||
$scope.responseValueAggs = null;
|
||||
try {
|
||||
|
@ -291,14 +292,16 @@ uiModules
|
|||
}
|
||||
};
|
||||
|
||||
function transferVisState(fromVis, toVis, fetch) {
|
||||
function transferVisState(fromVis, toVis, stage) {
|
||||
return function () {
|
||||
toVis.setState(fromVis.getState());
|
||||
const view = fromVis.getEnabledState();
|
||||
const full = fromVis.getState();
|
||||
toVis.setState(view);
|
||||
editableVis.dirty = false;
|
||||
$state.vis = vis.getState();
|
||||
$state.vis = full;
|
||||
$state.save();
|
||||
|
||||
if (fetch) $scope.fetch();
|
||||
if (stage) $scope.fetch();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ uiModules
|
|||
controllerAs: 'sidebar',
|
||||
controller: function ($scope) {
|
||||
$scope.$bind('vis', 'editableVis');
|
||||
$scope.$bind('outputVis', 'vis');
|
||||
$scope.$watch('vis.type', (visType) => {
|
||||
if (visType) {
|
||||
this.showData = visType.schemas.buckets || visType.schemas.metrics;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue