mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 01:13:23 -04:00
Merge remote-tracking branch 'origin/master' into feature/merge-code
This commit is contained in:
commit
602d39678f
445 changed files with 8565 additions and 8600 deletions
|
@ -20,9 +20,11 @@
|
|||
"xpack.apm": "x-pack/plugins/apm",
|
||||
"xpack.beatsManagement": "x-pack/plugins/beats_management",
|
||||
"xpack.crossClusterReplication": "x-pack/plugins/cross_cluster_replication",
|
||||
"xpack.dashboardMode": "x-pack/plugins/dashboard_mode",
|
||||
"xpack.graph": "x-pack/plugins/graph",
|
||||
"xpack.grokDebugger": "x-pack/plugins/grokdebugger",
|
||||
"xpack.idxMgmt": "x-pack/plugins/index_management",
|
||||
"xpack.indexLifecycleMgmt": "x-pack/plugins/index_lifecycle_management",
|
||||
"xpack.infra": "x-pack/plugins/infra",
|
||||
"xpack.licenseMgmt": "x-pack/plugins/license_management",
|
||||
"xpack.ml": "x-pack/plugins/ml",
|
||||
|
|
|
@ -80,7 +80,7 @@ POST api/kibana/dashboards/import?exclude=index-pattern
|
|||
"hits": 0,
|
||||
"description": "",
|
||||
"panelsJSON": "[{\"gridData\":{\"w\":24,\"h\":15,\"x\":0,\"y\":0,\"i\":\"1\"},\"version\":\"7.0.0-alpha1\",\"panelIndex\":\"1\",\"type\":\"visualization\",\"id\":\"80b956f0-b2cd-11e8-ad8e-85441f0c2e5c\",\"embeddableConfig\":{}}]",
|
||||
"optionsJSON": "{\"darkTheme\":false,\"useMargins\":true,\"hidePanelTitles\":false}",
|
||||
"optionsJSON": "{\"useMargins\":true,\"hidePanelTitles\":false}",
|
||||
"version": 1,
|
||||
"timeRestore": false,
|
||||
"kibanaSavedObjectMeta": {
|
||||
|
|
|
@ -28,7 +28,7 @@ the shortened URL token for the provided request body.
|
|||
--------------------------------------------------
|
||||
POST api/shorten_url
|
||||
{
|
||||
"url": "/app/kibana#/dashboard?_g=()&_a=(description:'',filters:!(),fullScreenMode:!f,options:(darkTheme:!f,hidePanelTitles:!f,useMargins:!t),panels:!((embeddableConfig:(),gridData:(h:15,i:'1',w:24,x:0,y:0),id:'8f4d0c00-4c86-11e8-b3d7-01146121b73d',panelIndex:'1',type:visualization,version:'7.0.0-alpha1')),query:(language:lucene,query:''),timeRestore:!f,title:'New%20Dashboard',viewMode:edit)",
|
||||
"url": "/app/kibana#/dashboard?_g=()&_a=(description:'',filters:!(),fullScreenMode:!f,options:(hidePanelTitles:!f,useMargins:!t),panels:!((embeddableConfig:(),gridData:(h:15,i:'1',w:24,x:0,y:0),id:'8f4d0c00-4c86-11e8-b3d7-01146121b73d',panelIndex:'1',type:visualization,version:'7.0.0-alpha1')),query:(language:lucene,query:''),timeRestore:!f,title:'New%20Dashboard',viewMode:edit)",
|
||||
}
|
||||
--------------------------------------------------
|
||||
// KIBANA
|
||||
|
|
|
@ -77,7 +77,6 @@ mentioned use "_default_".
|
|||
`timepicker:timeDefaults`:: The default time filter selection.
|
||||
`timepicker:refreshIntervalDefaults`:: The time filter's default refresh interval.
|
||||
`timepicker:quickRanges`:: The list of ranges to show in the Quick section of the time picker. This should be an array of objects, with each object containing `from`, `to` (see {ref}/common-options.html#date-math[accepted formats]), `display` (the title to be displayed), and `section` (which column to put the option in).
|
||||
`dashboard:defaultDarkTheme`:: Set this property to `true` to make new dashboards use the dark theme by default.
|
||||
`filters:pinnedByDefault`:: Set this property to `true` to make filters have a global state by default.
|
||||
`filterEditor:suggestValues`:: Set this property to `false` to prevent the filter editor from suggesting values for fields.
|
||||
`notifications:banner`:: You can specify a custom banner to display temporary notices to all users. This field supports
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
<titleabbrev>Collecting monitoring data with {metricbeat}</titleabbrev>
|
||||
++++
|
||||
|
||||
beta[]
|
||||
|
||||
In 6.4 and later, you can use {metricbeat} to collect data about {kib}
|
||||
and ship it to the monitoring cluster, rather than routing it through the
|
||||
production cluster as described in <<monitoring-kibana>>.
|
||||
|
|
|
@ -172,3 +172,6 @@ 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.
|
||||
`rollup.enabled:`:: *Default: true* Set this value to false to disable the Rollup user interface.
|
||||
|
||||
`license_management.enabled`:: *Default: true* Set this value to false to disable the License Management user interface.
|
11
package.json
11
package.json
|
@ -190,11 +190,11 @@
|
|||
"pug": "^2.0.3",
|
||||
"querystring-browser": "1.0.4",
|
||||
"raw-loader": "0.5.1",
|
||||
"react": "^16.3.0",
|
||||
"react": "^16.6.0",
|
||||
"react-addons-shallow-compare": "15.6.2",
|
||||
"react-anything-sortable": "^1.7.4",
|
||||
"react-color": "^2.13.8",
|
||||
"react-dom": "^16.3.0",
|
||||
"react-dom": "^16.6.0",
|
||||
"react-grid-layout": "^0.16.2",
|
||||
"react-input-range": "^1.3.0",
|
||||
"react-markdown": "^3.4.1",
|
||||
|
@ -325,9 +325,10 @@
|
|||
"classnames": "2.2.5",
|
||||
"dedent": "^0.7.0",
|
||||
"delete-empty": "^2.0.0",
|
||||
"enzyme": "3.2.0",
|
||||
"enzyme-adapter-react-16": "^1.1.1",
|
||||
"enzyme-to-json": "3.3.1",
|
||||
"enzyme": "^3.7.0",
|
||||
"enzyme-adapter-react-16": "^1.6.0",
|
||||
"enzyme-adapter-utils": "^1.8.1",
|
||||
"enzyme-to-json": "^3.3.4",
|
||||
"eslint": "^5.6.0",
|
||||
"eslint-config-prettier": "^3.1.0",
|
||||
"eslint-plugin-babel": "^5.2.0",
|
||||
|
|
|
@ -33,6 +33,7 @@ exports.help = (defaults = {}) => {
|
|||
--version Version of ES to download [default: ${defaults.version}]
|
||||
--base-path Path containing cache/installations [default: ${basePath}]
|
||||
--install-path Installation path, defaults to 'source' within base-path
|
||||
--data-archive Path to zip or tarball containing an ES data directory to seed the cluster with.
|
||||
--password Sets password for elastic user [default: ${password}]
|
||||
-E Additional key=value settings to pass to Elasticsearch
|
||||
--download-only Download the snapshot but don't actually start it
|
||||
|
@ -49,6 +50,7 @@ exports.run = async (defaults = {}) => {
|
|||
alias: {
|
||||
basePath: 'base-path',
|
||||
installPath: 'install-path',
|
||||
dataArchive: 'data-archive',
|
||||
esArgs: 'E',
|
||||
},
|
||||
|
||||
|
@ -62,6 +64,11 @@ exports.run = async (defaults = {}) => {
|
|||
await cluster.downloadSnapshot(options);
|
||||
} else {
|
||||
const { installPath } = await cluster.installSnapshot(options);
|
||||
|
||||
if (options.dataArchive) {
|
||||
await cluster.extractDataDirectory(installPath, options.dataArchive);
|
||||
}
|
||||
|
||||
await cluster.run(installPath, { esArgs: options.esArgs });
|
||||
}
|
||||
};
|
||||
|
|
|
@ -33,6 +33,7 @@ exports.help = (defaults = {}) => {
|
|||
--source-path Path to ES source [default: ${defaults['source-path']}]
|
||||
--base-path Path containing cache/installations [default: ${basePath}]
|
||||
--install-path Installation path, defaults to 'source' within base-path
|
||||
--data-archive Path to zip or tarball containing an ES data directory to seed the cluster with.
|
||||
--password Sets password for elastic user [default: ${password}]
|
||||
-E Additional key=value settings to pass to Elasticsearch
|
||||
|
||||
|
@ -49,6 +50,7 @@ exports.run = async (defaults = {}) => {
|
|||
basePath: 'base-path',
|
||||
installPath: 'install-path',
|
||||
sourcePath: 'source-path',
|
||||
dataArchive: 'data-archive',
|
||||
esArgs: 'E',
|
||||
},
|
||||
|
||||
|
@ -57,5 +59,10 @@ exports.run = async (defaults = {}) => {
|
|||
|
||||
const cluster = new Cluster();
|
||||
const { installPath } = await cluster.installSource(options);
|
||||
|
||||
if (options.dataArchive) {
|
||||
await cluster.extractDataDirectory(installPath, options.dataArchive);
|
||||
}
|
||||
|
||||
await cluster.run(installPath, { esArgs: options.esArgs });
|
||||
};
|
||||
|
|
|
@ -19,9 +19,10 @@
|
|||
|
||||
const execa = require('execa');
|
||||
const chalk = require('chalk');
|
||||
const path = require('path');
|
||||
const { downloadSnapshot, installSnapshot, installSource, installArchive } = require('./install');
|
||||
const { ES_BIN } = require('./paths');
|
||||
const { log: defaultLog, parseEsLog, extractConfigFiles } = require('./utils');
|
||||
const { log: defaultLog, parseEsLog, extractConfigFiles, decompress } = require('./utils');
|
||||
const { createCliError } = require('./errors');
|
||||
const { promisify } = require('util');
|
||||
const treeKillAsync = promisify(require('tree-kill'));
|
||||
|
@ -116,6 +117,28 @@ exports.Cluster = class Cluster {
|
|||
return { installPath };
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpakcs a tar or zip file containing the data directory for an
|
||||
* ES cluster.
|
||||
*
|
||||
* @param {String} installPath
|
||||
* @param {String} archivePath
|
||||
*/
|
||||
async extractDataDirectory(installPath, archivePath) {
|
||||
this._log.info(chalk.bold(`Extracting data directory`));
|
||||
this._log.indent(4);
|
||||
|
||||
// decompress excludes the root directory as that is how our archives are
|
||||
// structured. This works in our favor as we can explicitly extract into the data dir
|
||||
const extractPath = path.resolve(installPath, 'data');
|
||||
this._log.info(`Data archive: ${archivePath}`);
|
||||
this._log.info(`Extract path: ${extractPath}`);
|
||||
|
||||
await decompress(archivePath, extractPath);
|
||||
|
||||
this._log.indent(-4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts ES and returns resolved promise once started
|
||||
*
|
||||
|
|
|
@ -29,7 +29,6 @@ import { render } from './render';
|
|||
import { shape } from './shape';
|
||||
import { string } from './string';
|
||||
import { style } from './style';
|
||||
import { kibanaTable } from './kibana_table';
|
||||
import { kibanaContext } from './kibana_context';
|
||||
|
||||
export const typeSpecs = [
|
||||
|
@ -45,6 +44,5 @@ export const typeSpecs = [
|
|||
shape,
|
||||
string,
|
||||
style,
|
||||
kibanaTable,
|
||||
kibanaContext,
|
||||
];
|
||||
|
|
|
@ -20,3 +20,4 @@
|
|||
export { loadBrowserRegistries } from './browser_registries';
|
||||
export { createSocket } from './socket';
|
||||
export { initializeInterpreter } from './interpreter';
|
||||
export { RenderFunctionsRegistry } from './render_functions_registry';
|
||||
|
|
|
@ -17,20 +17,26 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import buildProcessorFunction from '../build_processor_function';
|
||||
import _ from 'lodash';
|
||||
import processors from '../response_processors/table';
|
||||
export function RenderFunction(config) {
|
||||
// This must match the name of the function that is used to create the `type: render` object
|
||||
this.name = config.name;
|
||||
|
||||
export default function handleResponseBody(panel) {
|
||||
return resp => {
|
||||
if (resp.error) {
|
||||
const err = new Error(resp.error.type);
|
||||
err.response = JSON.stringify(resp);
|
||||
throw err;
|
||||
}
|
||||
return panel.columns.map(column => {
|
||||
const processor = buildProcessorFunction(processors, resp, panel, column);
|
||||
return _.first(processor([]));
|
||||
});
|
||||
};
|
||||
// Use this to set a more friendly name
|
||||
this.displayName = config.displayName || this.name;
|
||||
|
||||
// A sentence or few about what this element does
|
||||
this.help = config.help;
|
||||
|
||||
// used to validate the data before calling the render function
|
||||
this.validate = config.validate || function validate() {};
|
||||
|
||||
// tell the renderer if the dom node should be reused, it's recreated each time by default
|
||||
this.reuseDomNode = Boolean(config.reuseDomNode);
|
||||
|
||||
// the function called to render the data
|
||||
this.render =
|
||||
config.render ||
|
||||
function render(domNode, data, done) {
|
||||
done();
|
||||
};
|
||||
}
|
|
@ -17,17 +17,13 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import buildRequestBody from './build_request_body';
|
||||
export default (req, panel, entities) => {
|
||||
const bodies = [];
|
||||
entities.forEach(entity => {
|
||||
bodies.push({
|
||||
index: panel.index_pattern,
|
||||
ignoreUnavailable: true,
|
||||
});
|
||||
const body = buildRequestBody(req, panel, entity);
|
||||
body.timeout = '90s';
|
||||
bodies.push(body);
|
||||
});
|
||||
return bodies;
|
||||
};
|
||||
import { Registry } from '../common';
|
||||
import { RenderFunction } from './render_function';
|
||||
|
||||
class RenderFunctionsRegistry extends Registry {
|
||||
wrapper(obj) {
|
||||
return new RenderFunction(obj);
|
||||
}
|
||||
}
|
||||
|
||||
export { RenderFunctionsRegistry };
|
|
@ -36,6 +36,7 @@ export function createEsTestCluster(options = {}) {
|
|||
log,
|
||||
basePath = resolve(KIBANA_ROOT, '.es'),
|
||||
esFrom = esTestConfig.getBuildFrom(),
|
||||
dataArchive,
|
||||
} = options;
|
||||
|
||||
const randomHash = Math.random()
|
||||
|
@ -74,6 +75,10 @@ export function createEsTestCluster(options = {}) {
|
|||
throw new Error(`unknown option esFrom "${esFrom}"`);
|
||||
}
|
||||
|
||||
if (dataArchive) {
|
||||
await cluster.extractDataDirectory(installPath, dataArchive);
|
||||
}
|
||||
|
||||
await cluster.start(installPath, {
|
||||
esArgs: [
|
||||
`cluster.name=${clusterName}`,
|
||||
|
|
|
@ -37,6 +37,7 @@ export async function runElasticsearch({ config, options }) {
|
|||
log,
|
||||
basePath: resolve(KIBANA_ROOT, '.es'),
|
||||
esFrom: esFrom || config.get('esTestCluster.from'),
|
||||
dataArchive: config.get('esTestCluster.dataArchive'),
|
||||
});
|
||||
|
||||
const esArgs = config.get('esTestCluster.serverArgs');
|
||||
|
|
|
@ -21,6 +21,7 @@ import chalk from 'chalk';
|
|||
import { chmod, unlink, writeFile } from 'fs';
|
||||
import dedent from 'dedent';
|
||||
import normalizePath from 'normalize-path';
|
||||
import os from 'os';
|
||||
import { resolve } from 'path';
|
||||
import { promisify } from 'util';
|
||||
import SimpleGit from 'simple-git';
|
||||
|
@ -128,7 +129,7 @@ export async function registerPrecommitGitHook(log) {
|
|||
await getPrecommitGitHookScriptPath(REPO_ROOT),
|
||||
getKbnPrecommitGitHookScript(
|
||||
REPO_ROOT,
|
||||
normalizePath(process.env.HOME.replace(/'/g, '\'')),
|
||||
normalizePath(os.homedir()),
|
||||
process.platform
|
||||
)
|
||||
);
|
||||
|
|
|
@ -139,6 +139,7 @@ export const schema = Joi.object().keys({
|
|||
license: Joi.string().default('oss'),
|
||||
from: Joi.string().default('snapshot'),
|
||||
serverArgs: Joi.array(),
|
||||
dataArchive: Joi.string(),
|
||||
}).default(),
|
||||
|
||||
kbnTestServer: Joi.object().keys({
|
||||
|
|
|
@ -34,6 +34,7 @@ describe('plugins/elasticsearch', () => {
|
|||
beforeEach(function () {
|
||||
server = {
|
||||
log: sinon.stub(),
|
||||
logWithMetadata: sinon.stub(),
|
||||
plugins: {
|
||||
elasticsearch: {
|
||||
getCluster: sinon.stub().withArgs('admin').returns({ callWithInternalUser: sinon.stub() }),
|
||||
|
@ -120,17 +121,17 @@ describe('plugins/elasticsearch', () => {
|
|||
it('warns if a node is only off by a patch version', async () => {
|
||||
setNodes('5.1.1');
|
||||
await ensureEsVersion(server, KIBANA_VERSION);
|
||||
sinon.assert.callCount(server.log, 2);
|
||||
expect(server.log.getCall(0).args[0]).to.contain('debug');
|
||||
expect(server.log.getCall(1).args[0]).to.contain('warning');
|
||||
sinon.assert.callCount(server.logWithMetadata, 2);
|
||||
expect(server.logWithMetadata.getCall(0).args[0]).to.contain('debug');
|
||||
expect(server.logWithMetadata.getCall(1).args[0]).to.contain('warning');
|
||||
});
|
||||
|
||||
it('warns if a node is off by a patch version and without http publish address', async () => {
|
||||
setNodeWithoutHTTP('5.1.1');
|
||||
await ensureEsVersion(server, KIBANA_VERSION);
|
||||
sinon.assert.callCount(server.log, 2);
|
||||
expect(server.log.getCall(0).args[0]).to.contain('debug');
|
||||
expect(server.log.getCall(1).args[0]).to.contain('warning');
|
||||
sinon.assert.callCount(server.logWithMetadata, 2);
|
||||
expect(server.logWithMetadata.getCall(0).args[0]).to.contain('debug');
|
||||
expect(server.logWithMetadata.getCall(1).args[0]).to.contain('warning');
|
||||
});
|
||||
|
||||
it('errors if a node incompatible and without http publish address', async () => {
|
||||
|
@ -147,28 +148,28 @@ describe('plugins/elasticsearch', () => {
|
|||
setNodes('5.1.1');
|
||||
|
||||
await ensureEsVersion(server, KIBANA_VERSION);
|
||||
sinon.assert.callCount(server.log, 2);
|
||||
expect(server.log.getCall(0).args[0]).to.contain('debug');
|
||||
expect(server.log.getCall(1).args[0]).to.contain('warning');
|
||||
sinon.assert.callCount(server.logWithMetadata, 2);
|
||||
expect(server.logWithMetadata.getCall(0).args[0]).to.contain('debug');
|
||||
expect(server.logWithMetadata.getCall(1).args[0]).to.contain('warning');
|
||||
|
||||
await ensureEsVersion(server, KIBANA_VERSION);
|
||||
sinon.assert.callCount(server.log, 3);
|
||||
expect(server.log.getCall(2).args[0]).to.contain('debug');
|
||||
sinon.assert.callCount(server.logWithMetadata, 3);
|
||||
expect(server.logWithMetadata.getCall(2).args[0]).to.contain('debug');
|
||||
});
|
||||
|
||||
it('warns again if the node list changes', async () => {
|
||||
setNodes('5.1.1');
|
||||
|
||||
await ensureEsVersion(server, KIBANA_VERSION);
|
||||
sinon.assert.callCount(server.log, 2);
|
||||
expect(server.log.getCall(0).args[0]).to.contain('debug');
|
||||
expect(server.log.getCall(1).args[0]).to.contain('warning');
|
||||
sinon.assert.callCount(server.logWithMetadata, 2);
|
||||
expect(server.logWithMetadata.getCall(0).args[0]).to.contain('debug');
|
||||
expect(server.logWithMetadata.getCall(1).args[0]).to.contain('warning');
|
||||
|
||||
setNodes('5.1.2');
|
||||
await ensureEsVersion(server, KIBANA_VERSION);
|
||||
sinon.assert.callCount(server.log, 4);
|
||||
expect(server.log.getCall(2).args[0]).to.contain('debug');
|
||||
expect(server.log.getCall(3).args[0]).to.contain('warning');
|
||||
sinon.assert.callCount(server.logWithMetadata, 4);
|
||||
expect(server.logWithMetadata.getCall(2).args[0]).to.contain('debug');
|
||||
expect(server.logWithMetadata.getCall(3).args[0]).to.contain('warning');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -85,7 +85,7 @@ describe('plugins/elasticsearch', () => {
|
|||
|
||||
// Setup the server mock
|
||||
server = {
|
||||
log: sinon.stub(),
|
||||
logWithMetadata: sinon.stub(),
|
||||
info: { port: 5601 },
|
||||
config: function () { return { get, set }; },
|
||||
plugins: {
|
||||
|
|
|
@ -54,7 +54,7 @@ export function createProxy(server) {
|
|||
handler(req, h) {
|
||||
const { query, payload: body } = req;
|
||||
return callWithRequest(req, 'transport.request', {
|
||||
path: `/${req.params.index}/_search`,
|
||||
path: `/${encodeURIComponent(req.params.index)}/_search`,
|
||||
method: 'POST',
|
||||
query,
|
||||
body
|
||||
|
|
|
@ -40,7 +40,7 @@ export function ensureEsVersion(server, kibanaVersion) {
|
|||
const { callWithInternalUser } = server.plugins.elasticsearch.getCluster('admin');
|
||||
const isProd = server.config().get('env.prod');
|
||||
|
||||
server.log(['plugin', 'debug'], 'Checking Elasticsearch version');
|
||||
server.logWithMetadata(['plugin', 'debug'], 'Checking Elasticsearch version');
|
||||
return callWithInternalUser('nodes.info', {
|
||||
filterPath: [
|
||||
'nodes.*.version',
|
||||
|
@ -92,15 +92,14 @@ export function ensureEsVersion(server, kibanaVersion) {
|
|||
const warningNodeNames = getHumanizedNodeNames(simplifiedNodes).join(', ');
|
||||
if (lastWarnedNodesForServer.get(server) !== warningNodeNames) {
|
||||
lastWarnedNodesForServer.set(server, warningNodeNames);
|
||||
server.log(['warning'], {
|
||||
tmpl: (
|
||||
`You're running Kibana ${kibanaVersion} with some different versions of ` +
|
||||
server.logWithMetadata(['warning'],
|
||||
`You're running Kibana ${kibanaVersion} with some different versions of ` +
|
||||
'Elasticsearch. Update Kibana or Elasticsearch to the same ' +
|
||||
`version to prevent compatibility issues: ${warningNodeNames}`
|
||||
),
|
||||
kibanaVersion,
|
||||
nodes: simplifiedNodes,
|
||||
});
|
||||
`version to prevent compatibility issues: ${warningNodeNames}`,
|
||||
{
|
||||
kibanaVersion,
|
||||
nodes: simplifiedNodes,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ const courierRequestHandler = courierRequestHandlerProvider().handler;
|
|||
|
||||
export const esaggs = () => ({
|
||||
name: 'esaggs',
|
||||
type: 'kibana_table',
|
||||
type: 'datatable',
|
||||
context: {
|
||||
types: [
|
||||
'kibana_context',
|
||||
|
@ -90,9 +90,12 @@ export const esaggs = () => ({
|
|||
});
|
||||
|
||||
return {
|
||||
type: 'kibana_table',
|
||||
index: args.index,
|
||||
...response,
|
||||
type: 'datatable',
|
||||
rows: response.rows,
|
||||
columns: response.columns.map(column => ({
|
||||
id: column.id,
|
||||
name: column.name,
|
||||
})),
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
|
@ -24,7 +24,7 @@ export const metric = () => ({
|
|||
type: 'render',
|
||||
context: {
|
||||
types: [
|
||||
'kibana_table'
|
||||
'datatable'
|
||||
],
|
||||
},
|
||||
help: i18n.translate('interpreter.functions.metric.help', {
|
||||
|
|
|
@ -26,7 +26,7 @@ export const kibanaPie = () => ({
|
|||
type: 'render',
|
||||
context: {
|
||||
types: [
|
||||
'kibana_table', 'null'
|
||||
'datatable'
|
||||
],
|
||||
},
|
||||
help: i18n.translate('interpreter.functions.pie.help', {
|
||||
|
|
|
@ -24,7 +24,7 @@ export const regionmap = () => ({
|
|||
type: 'render',
|
||||
context: {
|
||||
types: [
|
||||
'kibana_table'
|
||||
'datatable'
|
||||
],
|
||||
},
|
||||
help: i18n.translate('interpreter.functions.regionmap.help', {
|
||||
|
|
|
@ -28,7 +28,7 @@ export const kibanaTable = () => ({
|
|||
type: 'render',
|
||||
context: {
|
||||
types: [
|
||||
'kibana_table'
|
||||
'datatable'
|
||||
],
|
||||
},
|
||||
help: i18n.translate('interpreter.functions.table.help', {
|
||||
|
|
|
@ -24,7 +24,7 @@ export const tagcloud = () => ({
|
|||
type: 'render',
|
||||
context: {
|
||||
types: [
|
||||
'kibana_table'
|
||||
'datatable'
|
||||
],
|
||||
},
|
||||
help: i18n.translate('interpreter.functions.tagcloud.help', {
|
||||
|
|
|
@ -25,7 +25,7 @@ export const tilemap = () => ({
|
|||
type: 'render',
|
||||
context: {
|
||||
types: [
|
||||
'kibana_table'
|
||||
'datatable'
|
||||
],
|
||||
},
|
||||
help: i18n.translate('interpreter.functions.tilemap.help', {
|
||||
|
|
|
@ -26,7 +26,7 @@ export const vislib = () => ({
|
|||
type: 'render',
|
||||
context: {
|
||||
types: [
|
||||
'kibana_table', 'null'
|
||||
'datatable'
|
||||
],
|
||||
},
|
||||
help: i18n.translate('interpreter.functions.vislib.help', {
|
||||
|
|
|
@ -44,9 +44,6 @@ function getHandler(from, type) {
|
|||
export const visualization = () => ({
|
||||
name: 'visualization',
|
||||
type: 'render',
|
||||
context: {
|
||||
types: [],
|
||||
},
|
||||
help: i18n.translate('interpreter.functions.visualization.help', {
|
||||
defaultMessage: 'A simple visualization'
|
||||
}),
|
||||
|
|
|
@ -23,11 +23,13 @@ import chrome from 'ui/chrome';
|
|||
import { functions } from './functions';
|
||||
import { functionsRegistry } from './functions_registry';
|
||||
import { typesRegistry } from './types_registry';
|
||||
import { renderFunctionsRegistry } from './render_functions_registry';
|
||||
|
||||
const basePath = chrome.getBasePath();
|
||||
|
||||
const types = {
|
||||
browserFunctions: functionsRegistry,
|
||||
renderers: renderFunctionsRegistry,
|
||||
types: typesRegistry
|
||||
};
|
||||
|
||||
|
|
|
@ -17,25 +17,6 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
export const kibanaTable = () => ({
|
||||
name: 'kibana_table',
|
||||
serialize: context => {
|
||||
context.columns.forEach(column => {
|
||||
column.aggConfig = column.aggConfig.toJSON();
|
||||
});
|
||||
return context;
|
||||
},
|
||||
validate: tabify => {
|
||||
if (!tabify.columns) {
|
||||
throw new Error('tabify must have a columns array, even if it is empty');
|
||||
}
|
||||
},
|
||||
from: {
|
||||
null: () => {
|
||||
return {
|
||||
type: 'kibana_table',
|
||||
columns: [],
|
||||
};
|
||||
},
|
||||
},
|
||||
});
|
||||
import { RenderFunctionsRegistry } from '@kbn/interpreter/public';
|
||||
|
||||
export const renderFunctionsRegistry = new RenderFunctionsRegistry();
|
|
@ -103,7 +103,7 @@ export const createHeartbeatInstructions = context => ({
|
|||
defaultMessage: 'Start Heartbeat',
|
||||
}),
|
||||
textPre: i18n.translate('kbn.common.tutorials.heartbeatInstructions.start.osxTextPre', {
|
||||
defaultMessage: 'The `setup` command loads the Kibana dashboards. If the dashboards are already set up, omit this command.',
|
||||
defaultMessage: 'The `setup` command loads the Kibana index pattern.',
|
||||
}),
|
||||
commands: [
|
||||
'./heartbeat setup',
|
||||
|
@ -115,7 +115,7 @@ export const createHeartbeatInstructions = context => ({
|
|||
defaultMessage: 'Start Heartbeat',
|
||||
}),
|
||||
textPre: i18n.translate('kbn.common.tutorials.heartbeatInstructions.start.debTextPre', {
|
||||
defaultMessage: 'The `setup` command loads the Kibana dashboards. If the dashboards are already set up, omit this command.',
|
||||
defaultMessage: 'The `setup` command loads the Kibana index pattern.',
|
||||
}),
|
||||
commands: [
|
||||
'sudo heartbeat setup',
|
||||
|
@ -127,7 +127,7 @@ export const createHeartbeatInstructions = context => ({
|
|||
defaultMessage: 'Start Heartbeat',
|
||||
}),
|
||||
textPre: i18n.translate('kbn.common.tutorials.heartbeatInstructions.start.rpmTextPre', {
|
||||
defaultMessage: 'The `setup` command loads the Kibana dashboards. If the dashboards are already set up, omit this command.',
|
||||
defaultMessage: 'The `setup` command loads the Kibana index pattern.',
|
||||
}),
|
||||
commands: [
|
||||
'sudo heartbeat setup',
|
||||
|
@ -139,7 +139,7 @@ export const createHeartbeatInstructions = context => ({
|
|||
defaultMessage: 'Start Heartbeat',
|
||||
}),
|
||||
textPre: i18n.translate('kbn.common.tutorials.heartbeatInstructions.start.windowsTextPre', {
|
||||
defaultMessage: 'The `setup` command loads the Kibana dashboards. If the dashboards are already set up, omit this command.',
|
||||
defaultMessage: 'The `setup` command loads the Kibana index pattern.',
|
||||
}),
|
||||
commands: [
|
||||
'.\\heartbeat.exe setup',
|
||||
|
|
|
@ -110,7 +110,6 @@ State communicated to the embeddable.
|
|||
// TODO:
|
||||
filters: FilterObject,
|
||||
timeRange: TimeRangeObject,
|
||||
darkTheme: boolean,
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -18,191 +18,3 @@ dashboard-listing {
|
|||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Dark theme bootstrap
|
||||
// Yes, this is a hack because bootstrap will be removed and everything must move to EUI theming
|
||||
// Can't reliably remove all/any of these because of embeddables
|
||||
|
||||
.theme-dark {
|
||||
@import '@elastic/eui/src/themes/k6/k6_colors_dark';
|
||||
|
||||
// /src/ui/public/styles/bootstrap/scaffolding.less
|
||||
a {
|
||||
color: $euiColorPrimary;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: darken($euiColorPrimary, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
// /src/ui/public/styles/bootstrap/forms.less
|
||||
// Updated to match EUI dark theme
|
||||
.form-control {
|
||||
color: $euiTextColor;
|
||||
background-color: tintOrShade($euiColorLightestShade, 60%, 25%);
|
||||
border-color: transparentize($euiColorFullShade, .9);
|
||||
&[disabled],
|
||||
&[readonly],
|
||||
fieldset[disabled] & {
|
||||
background-color: darken($euiColorLightestShade, 2%);
|
||||
}
|
||||
}
|
||||
|
||||
// /src/ui/public/styles/bootstrap/tables.less
|
||||
// Updated to match EUI dark theme
|
||||
.table {
|
||||
// Cells
|
||||
> thead,
|
||||
> tbody,
|
||||
> tfoot {
|
||||
> tr {
|
||||
> th,
|
||||
> td {
|
||||
border-top-color: $euiColorLightShade;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Bottom align for column headings
|
||||
> thead > tr > th {
|
||||
border-bottom-color: $euiColorLightShade;
|
||||
}
|
||||
// Account for multiple tbody instances
|
||||
> tbody + tbody {
|
||||
border-top-color: $euiColorLightShade;
|
||||
}
|
||||
|
||||
// Nesting
|
||||
.table {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
th {
|
||||
i.fa-sort {
|
||||
color: $euiColorMediumShade;
|
||||
}
|
||||
|
||||
button.fa-sort-asc,
|
||||
button.fa-sort-down,
|
||||
i.fa-sort-asc,
|
||||
i.fa-sort-down {
|
||||
color: $euiTextColor;
|
||||
}
|
||||
|
||||
button.fa-sort-desc,
|
||||
button.fa-sort-up,
|
||||
i.fa-sort-desc,
|
||||
i.fa-sort-up {
|
||||
color: $euiTextColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// /src/ui/public/styles/bootstrap/list-group.less
|
||||
.list-group-item {
|
||||
background-color: $euiColorLightShade;
|
||||
border-color: $euiColorDarkShade;
|
||||
&:nth-child(even) {
|
||||
background-color: $euiColorMediumShade;
|
||||
}
|
||||
}
|
||||
|
||||
a.list-group-item,
|
||||
button.list-group-item {
|
||||
color: $euiColorMediumShade;
|
||||
|
||||
.list-group-item-heading {
|
||||
color: $euiColorLightShade;
|
||||
}
|
||||
|
||||
// Hover state
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: $euiColorMediumShade;
|
||||
background-color: $euiColorDarkestShade;
|
||||
}
|
||||
}
|
||||
|
||||
.panel {
|
||||
> .panel-body + .table,
|
||||
> .panel-body + .table-responsive,
|
||||
> .table + .panel-body,
|
||||
> .table-responsive + .panel-body {
|
||||
border-top-color: $euiColorMediumShade;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-group {
|
||||
.panel-heading {
|
||||
+ .panel-collapse > .panel-body,
|
||||
+ .panel-collapse > .list-group {
|
||||
border-top-color: $euiColorEmptyShade;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-footer {
|
||||
border-top: 0;
|
||||
+ .panel-collapse .panel-body {
|
||||
border-bottom-color: $euiColorEmptyShade;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.panel-default {
|
||||
& > .panel-heading {
|
||||
color: $euiColorPrimary;
|
||||
background-color: $euiColorEmptyShade;
|
||||
border-color: $euiColorLightShade;
|
||||
|
||||
+ .panel-collapse > .panel-body {
|
||||
border-top-color: $euiColorLightShade;
|
||||
}
|
||||
.badge {
|
||||
color: $euiColorEmptyShade;
|
||||
background-color: $euiColorPrimary;
|
||||
}
|
||||
}
|
||||
& > .panel-footer {
|
||||
+ .panel-collapse > .panel-body {
|
||||
border-bottom-color: $euiColorLightShade;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// /src/ui/public/styles/bootstrap/navs.less
|
||||
.nav {
|
||||
> li {
|
||||
> a {
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: $euiColorDarkShade;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nav-tabs {
|
||||
border-bottom-color: $euiColorMediumShade;
|
||||
> li {
|
||||
> a {
|
||||
&:hover {
|
||||
border-color: $euiColorDarkShade;
|
||||
}
|
||||
}
|
||||
|
||||
&.active > a {
|
||||
&,
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: $euiColorFullShade;
|
||||
background-color: $euiColorMediumShade;
|
||||
border: 0 none transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,35 +13,8 @@
|
|||
// dshChart__legend--small
|
||||
// dshChart__legend-isLoading
|
||||
|
||||
/**
|
||||
* 1. Don't duplicate styles in dark mode
|
||||
*/
|
||||
.theme-light { /* 1 */
|
||||
@import 'dashboard_app';
|
||||
@import 'grid/index';
|
||||
@import 'panel/index';
|
||||
@import 'viewport/index';
|
||||
}
|
||||
|
||||
// Imports outside of theme selector don't change between light/dark modes
|
||||
@import 'dashboard_app';
|
||||
@import 'grid/index';
|
||||
@import 'panel/index';
|
||||
@import 'viewport/index';
|
||||
@import 'components/index';
|
||||
|
||||
// Must be outside of theme selector because it lives in a portal
|
||||
@import 'panel/panel_header/panel_options_menu_form';
|
||||
|
||||
// DARK THEME
|
||||
// EUI global scope -- dark
|
||||
@import '@elastic/eui/src/themes/k6/k6_colors_dark';
|
||||
|
||||
.theme-dark {
|
||||
background-color: $euiColorEmptyShade;
|
||||
|
||||
@import 'dashboard_app';
|
||||
@import 'grid/index';
|
||||
@import 'panel/index';
|
||||
@import 'viewport/index';
|
||||
|
||||
// Vis imports
|
||||
@import 'src/ui/public/vis/index';
|
||||
@import 'src/ui/public/vislib/index';
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ import React from 'react';
|
|||
import angular from 'angular';
|
||||
import { uiModules } from 'ui/modules';
|
||||
import chrome from 'ui/chrome';
|
||||
import { applyTheme } from 'ui/theme';
|
||||
import { toastNotifications } from 'ui/notify';
|
||||
|
||||
import 'ui/query_bar';
|
||||
|
@ -230,8 +229,6 @@ app.directive('dashboardApp', function ($injector) {
|
|||
$scope.refresh();
|
||||
};
|
||||
|
||||
updateTheme();
|
||||
|
||||
$scope.indexPatterns = [];
|
||||
|
||||
$scope.onPanelRemoved = (panelIndex) => {
|
||||
|
@ -433,11 +430,6 @@ app.directive('dashboardApp', function ($injector) {
|
|||
navActions[TopNavIds.OPTIONS] = (menuItem, navController, anchorElement) => {
|
||||
showOptionsPopover({
|
||||
anchorElement,
|
||||
darkTheme: dashboardStateManager.getDarkTheme(),
|
||||
onDarkThemeChange: (isChecked) => {
|
||||
dashboardStateManager.setDarkTheme(isChecked);
|
||||
updateTheme();
|
||||
},
|
||||
useMargins: dashboardStateManager.getUseMargins(),
|
||||
onUseMarginsChange: (isChecked) => {
|
||||
dashboardStateManager.setUseMargins(isChecked);
|
||||
|
@ -475,27 +467,8 @@ app.directive('dashboardApp', function ($injector) {
|
|||
|
||||
$scope.$on('$destroy', () => {
|
||||
dashboardStateManager.destroy();
|
||||
|
||||
// Remove dark theme to keep it from affecting the appearance of other apps.
|
||||
setLightTheme();
|
||||
});
|
||||
|
||||
function updateTheme() {
|
||||
dashboardStateManager.getDarkTheme() ? setDarkTheme() : setLightTheme();
|
||||
}
|
||||
|
||||
function setDarkTheme() {
|
||||
chrome.removeApplicationClass(['theme-light']);
|
||||
chrome.addApplicationClass('theme-dark');
|
||||
applyTheme('dark');
|
||||
}
|
||||
|
||||
function setLightTheme() {
|
||||
chrome.removeApplicationClass(['theme-dark']);
|
||||
chrome.addApplicationClass('theme-light');
|
||||
applyTheme('light');
|
||||
}
|
||||
|
||||
if ($route.current.params && $route.current.params[DashboardConstants.NEW_VISUALIZATION_ID_PARAM]) {
|
||||
dashboardStateManager.addNewPanel($route.current.params[DashboardConstants.NEW_VISUALIZATION_ID_PARAM], 'visualization');
|
||||
|
||||
|
|
|
@ -369,15 +369,6 @@ export class DashboardStateManager {
|
|||
this.saveState();
|
||||
}
|
||||
|
||||
getDarkTheme() {
|
||||
return this.appState.options.darkTheme;
|
||||
}
|
||||
|
||||
setDarkTheme(darkTheme) {
|
||||
this.appState.options.darkTheme = darkTheme;
|
||||
this.saveState();
|
||||
}
|
||||
|
||||
getTimeRestore() {
|
||||
return this.appState.timeRestore;
|
||||
}
|
||||
|
|
|
@ -524,50 +524,48 @@ exports[`after fetch renders warning when listingLimit is exceeded 1`] = `
|
|||
<EuiSpacer
|
||||
size="m"
|
||||
/>
|
||||
<React.Fragment>
|
||||
<EuiCallOut
|
||||
color="warning"
|
||||
iconType="help"
|
||||
size="m"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Listing limit exceeded"
|
||||
id="kbn.dashboard.listing.listingLimitExceededTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="You have {totalDashboards} dashboards, but your {listingLimitText} setting prevents the table below from displaying more than {listingLimitValue}. You can change this setting under {advancedSettingsLink}."
|
||||
id="kbn.dashboard.listing.listingLimitExceededDescription"
|
||||
values={
|
||||
Object {
|
||||
"advancedSettingsLink": <EuiLink
|
||||
color="primary"
|
||||
href="#/management/kibana/settings"
|
||||
type="button"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Advanced Settings"
|
||||
id="kbn.dashboard.listing.listingLimitExceeded.advancedSettingsLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
"listingLimitText": <strong>
|
||||
listingLimit
|
||||
</strong>,
|
||||
"listingLimitValue": 1,
|
||||
"totalDashboards": 2,
|
||||
}
|
||||
<EuiCallOut
|
||||
color="warning"
|
||||
iconType="help"
|
||||
size="m"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Listing limit exceeded"
|
||||
id="kbn.dashboard.listing.listingLimitExceededTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="You have {totalDashboards} dashboards, but your {listingLimitText} setting prevents the table below from displaying more than {listingLimitValue}. You can change this setting under {advancedSettingsLink}."
|
||||
id="kbn.dashboard.listing.listingLimitExceededDescription"
|
||||
values={
|
||||
Object {
|
||||
"advancedSettingsLink": <EuiLink
|
||||
color="primary"
|
||||
href="#/management/kibana/settings"
|
||||
type="button"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Advanced Settings"
|
||||
id="kbn.dashboard.listing.listingLimitExceeded.advancedSettingsLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
"listingLimitText": <strong>
|
||||
listingLimit
|
||||
</strong>,
|
||||
"listingLimitValue": 1,
|
||||
"totalDashboards": 2,
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
<EuiSpacer
|
||||
size="m"
|
||||
/>
|
||||
</React.Fragment>
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
<EuiSpacer
|
||||
size="m"
|
||||
/>
|
||||
<EuiFlexGroup
|
||||
alignItems="stretch"
|
||||
component="div"
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
@import "./dashboard_panel";
|
||||
@import 'panel_header/panel_options_menu_form';
|
||||
|
|
|
@ -48,7 +48,6 @@ module.factory('SavedDashboard', function (Private, config, i18n) {
|
|||
description: '',
|
||||
panelsJSON: '[]',
|
||||
optionsJSON: angular.toJson({
|
||||
darkTheme: config.get('dashboard:defaultDarkTheme'),
|
||||
// for BWC reasons we can't default dashboards that already exist without this setting to true.
|
||||
useMargins: id ? false : true,
|
||||
hidePanelTitles: false,
|
||||
|
|
|
@ -30,17 +30,10 @@ import {
|
|||
class OptionsMenuUi extends Component {
|
||||
|
||||
state = {
|
||||
darkTheme: this.props.darkTheme,
|
||||
useMargins: this.props.useMargins,
|
||||
hidePanelTitles: this.props.hidePanelTitles,
|
||||
}
|
||||
|
||||
handleDarkThemeChange = (evt) => {
|
||||
const isChecked = evt.target.checked;
|
||||
this.props.onDarkThemeChange(isChecked);
|
||||
this.setState({ darkTheme: isChecked });
|
||||
}
|
||||
|
||||
handleUseMarginsChange = (evt) => {
|
||||
const isChecked = evt.target.checked;
|
||||
this.props.onUseMarginsChange(isChecked);
|
||||
|
@ -59,18 +52,6 @@ class OptionsMenuUi extends Component {
|
|||
data-test-subj="dashboardOptionsMenu"
|
||||
>
|
||||
|
||||
<EuiFormRow>
|
||||
<EuiSwitch
|
||||
label={this.props.intl.formatMessage({
|
||||
id: 'kbn.dashboard.topNav.options.useDarkThemeSwitchLabel',
|
||||
defaultMessage: 'Use dark theme',
|
||||
})}
|
||||
checked={this.state.darkTheme}
|
||||
onChange={this.handleDarkThemeChange}
|
||||
data-test-subj="dashboardDarkThemeCheckbox"
|
||||
/>
|
||||
</EuiFormRow>
|
||||
|
||||
<EuiFormRow>
|
||||
<EuiSwitch
|
||||
label={this.props.intl.formatMessage({
|
||||
|
@ -101,8 +82,6 @@ class OptionsMenuUi extends Component {
|
|||
}
|
||||
|
||||
OptionsMenuUi.propTypes = {
|
||||
darkTheme: PropTypes.bool.isRequired,
|
||||
onDarkThemeChange: PropTypes.func.isRequired,
|
||||
useMargins: PropTypes.bool.isRequired,
|
||||
onUseMarginsChange: PropTypes.func.isRequired,
|
||||
hidePanelTitles: PropTypes.bool.isRequired,
|
||||
|
|
|
@ -38,8 +38,6 @@ const onClose = () => {
|
|||
|
||||
export function showOptionsPopover({
|
||||
anchorElement,
|
||||
darkTheme,
|
||||
onDarkThemeChange,
|
||||
useMargins,
|
||||
onUseMarginsChange,
|
||||
hidePanelTitles,
|
||||
|
@ -64,8 +62,6 @@ export function showOptionsPopover({
|
|||
closePopover={onClose}
|
||||
>
|
||||
<OptionsMenu
|
||||
darkTheme={darkTheme}
|
||||
onDarkThemeChange={onDarkThemeChange}
|
||||
useMargins={useMargins}
|
||||
onUseMarginsChange={onUseMarginsChange}
|
||||
hidePanelTitles={hidePanelTitles}
|
||||
|
|
|
@ -1012,22 +1012,20 @@ exports[`home should render home component 1`] = `
|
|||
<EuiPageBody
|
||||
restrictWidth={false}
|
||||
>
|
||||
<React.Fragment>
|
||||
<RecentlyAccessed
|
||||
recentlyAccessed={
|
||||
Array [
|
||||
Object {
|
||||
"id": "1",
|
||||
"label": "my vis",
|
||||
"link": "link_to_my_vis",
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
</React.Fragment>
|
||||
<RecentlyAccessed
|
||||
recentlyAccessed={
|
||||
Array [
|
||||
Object {
|
||||
"id": "1",
|
||||
"label": "my vis",
|
||||
"link": "link_to_my_vis",
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
<InjectIntl(AddDataUi)
|
||||
apmUiEnabled={true}
|
||||
isNewKibanaInstance={false}
|
||||
|
|
|
@ -49,82 +49,74 @@ exports[`render 1`] = `
|
|||
responsive={true}
|
||||
wrap={false}
|
||||
>
|
||||
<React.Fragment
|
||||
key="0"
|
||||
>
|
||||
<EuiFlexItem
|
||||
className="homRecentlyAccessed__item"
|
||||
component="div"
|
||||
grow={false}
|
||||
style={
|
||||
Object {
|
||||
"minWidth": "3.9000000000000004em",
|
||||
}
|
||||
<EuiFlexItem
|
||||
className="homRecentlyAccessed__item"
|
||||
component="div"
|
||||
grow={false}
|
||||
style={
|
||||
Object {
|
||||
"minWidth": "3.9000000000000004em",
|
||||
}
|
||||
>
|
||||
<EuiToolTip
|
||||
anchorClassName="homRecentlyAccessed__anchor"
|
||||
content="label0"
|
||||
delay="regular"
|
||||
position="bottom"
|
||||
>
|
||||
<EuiLink
|
||||
className="homRecentlyAccessed__longLink"
|
||||
color="primary"
|
||||
href="link0"
|
||||
type="button"
|
||||
>
|
||||
label0
|
||||
</EuiLink>
|
||||
</EuiToolTip>
|
||||
</EuiFlexItem>
|
||||
</React.Fragment>
|
||||
<React.Fragment
|
||||
key="1"
|
||||
}
|
||||
>
|
||||
<EuiFlexItem
|
||||
className="homRecentlyAccessed__separator"
|
||||
component="div"
|
||||
grow={false}
|
||||
<EuiToolTip
|
||||
anchorClassName="homRecentlyAccessed__anchor"
|
||||
content="label0"
|
||||
delay="regular"
|
||||
position="bottom"
|
||||
>
|
||||
<EuiText
|
||||
grow={true}
|
||||
<EuiLink
|
||||
className="homRecentlyAccessed__longLink"
|
||||
color="primary"
|
||||
href="link0"
|
||||
type="button"
|
||||
>
|
||||
label0
|
||||
</EuiLink>
|
||||
</EuiToolTip>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
className="homRecentlyAccessed__separator"
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiText
|
||||
grow={true}
|
||||
size="m"
|
||||
>
|
||||
<EuiIcon
|
||||
color="subdued"
|
||||
size="m"
|
||||
>
|
||||
<EuiIcon
|
||||
color="subdued"
|
||||
size="m"
|
||||
type="dot"
|
||||
/>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
className="homRecentlyAccessed__item"
|
||||
component="div"
|
||||
grow={false}
|
||||
style={
|
||||
Object {
|
||||
"minWidth": "3.9000000000000004em",
|
||||
}
|
||||
type="dot"
|
||||
/>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
className="homRecentlyAccessed__item"
|
||||
component="div"
|
||||
grow={false}
|
||||
style={
|
||||
Object {
|
||||
"minWidth": "3.9000000000000004em",
|
||||
}
|
||||
}
|
||||
>
|
||||
<EuiToolTip
|
||||
anchorClassName="homRecentlyAccessed__anchor"
|
||||
content="label1"
|
||||
delay="regular"
|
||||
position="bottom"
|
||||
>
|
||||
<EuiToolTip
|
||||
anchorClassName="homRecentlyAccessed__anchor"
|
||||
content="label1"
|
||||
delay="regular"
|
||||
position="bottom"
|
||||
<EuiLink
|
||||
className="homRecentlyAccessed__longLink"
|
||||
color="primary"
|
||||
href="link1"
|
||||
type="button"
|
||||
>
|
||||
<EuiLink
|
||||
className="homRecentlyAccessed__longLink"
|
||||
color="primary"
|
||||
href="link1"
|
||||
type="button"
|
||||
>
|
||||
label1
|
||||
</EuiLink>
|
||||
</EuiToolTip>
|
||||
</EuiFlexItem>
|
||||
</React.Fragment>
|
||||
label1
|
||||
</EuiLink>
|
||||
</EuiToolTip>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
|
|
|
@ -8,32 +8,30 @@ exports[`isCloudEnabled is false should not render instruction toggle when ON_PR
|
|||
<EuiPageBody
|
||||
restrictWidth={false}
|
||||
>
|
||||
<React.Fragment>
|
||||
<div>
|
||||
<EuiLink
|
||||
color="primary"
|
||||
href="#/home"
|
||||
type="button"
|
||||
>
|
||||
Home
|
||||
</EuiLink>
|
||||
/
|
||||
|
||||
<EuiLink
|
||||
color="primary"
|
||||
href="#/home/tutorial_directory"
|
||||
type="button"
|
||||
>
|
||||
Add data
|
||||
</EuiLink>
|
||||
/
|
||||
|
||||
jest test tutorial
|
||||
</div>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
</React.Fragment>
|
||||
<div>
|
||||
<EuiLink
|
||||
color="primary"
|
||||
href="#/home"
|
||||
type="button"
|
||||
>
|
||||
Home
|
||||
</EuiLink>
|
||||
/
|
||||
|
||||
<EuiLink
|
||||
color="primary"
|
||||
href="#/home/tutorial_directory"
|
||||
type="button"
|
||||
>
|
||||
Add data
|
||||
</EuiLink>
|
||||
/
|
||||
|
||||
jest test tutorial
|
||||
</div>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
<div>
|
||||
<InjectIntl(IntroductionUI)
|
||||
description="tutorial used to drive jest tests"
|
||||
|
@ -89,32 +87,30 @@ exports[`isCloudEnabled is false should render ON_PREM instructions with instruc
|
|||
<EuiPageBody
|
||||
restrictWidth={false}
|
||||
>
|
||||
<React.Fragment>
|
||||
<div>
|
||||
<EuiLink
|
||||
color="primary"
|
||||
href="#/home"
|
||||
type="button"
|
||||
>
|
||||
Home
|
||||
</EuiLink>
|
||||
/
|
||||
|
||||
<EuiLink
|
||||
color="primary"
|
||||
href="#/home/tutorial_directory"
|
||||
type="button"
|
||||
>
|
||||
Add data
|
||||
</EuiLink>
|
||||
/
|
||||
|
||||
jest test tutorial
|
||||
</div>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
</React.Fragment>
|
||||
<div>
|
||||
<EuiLink
|
||||
color="primary"
|
||||
href="#/home"
|
||||
type="button"
|
||||
>
|
||||
Home
|
||||
</EuiLink>
|
||||
/
|
||||
|
||||
<EuiLink
|
||||
color="primary"
|
||||
href="#/home/tutorial_directory"
|
||||
type="button"
|
||||
>
|
||||
Add data
|
||||
</EuiLink>
|
||||
/
|
||||
|
||||
jest test tutorial
|
||||
</div>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
<div>
|
||||
<InjectIntl(IntroductionUI)
|
||||
description="tutorial used to drive jest tests"
|
||||
|
@ -263,32 +259,30 @@ exports[`should render ELASTIC_CLOUD instructions when isCloudEnabled is true 1`
|
|||
<EuiPageBody
|
||||
restrictWidth={false}
|
||||
>
|
||||
<React.Fragment>
|
||||
<div>
|
||||
<EuiLink
|
||||
color="primary"
|
||||
href="#/home"
|
||||
type="button"
|
||||
>
|
||||
Home
|
||||
</EuiLink>
|
||||
/
|
||||
|
||||
<EuiLink
|
||||
color="primary"
|
||||
href="#/home/tutorial_directory"
|
||||
type="button"
|
||||
>
|
||||
Add data
|
||||
</EuiLink>
|
||||
/
|
||||
|
||||
jest test tutorial
|
||||
</div>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
</React.Fragment>
|
||||
<div>
|
||||
<EuiLink
|
||||
color="primary"
|
||||
href="#/home"
|
||||
type="button"
|
||||
>
|
||||
Home
|
||||
</EuiLink>
|
||||
/
|
||||
|
||||
<EuiLink
|
||||
color="primary"
|
||||
href="#/home/tutorial_directory"
|
||||
type="button"
|
||||
>
|
||||
Add data
|
||||
</EuiLink>
|
||||
/
|
||||
|
||||
jest test tutorial
|
||||
</div>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
<div>
|
||||
<InjectIntl(IntroductionUI)
|
||||
description="tutorial used to drive jest tests"
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 147 KiB After Width: | Height: | Size: 50 KiB |
|
@ -1,7 +1,7 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`CreateIndexPatternWizard defaults to the loading state 1`] = `
|
||||
<React.Fragment>
|
||||
<Fragment>
|
||||
<div>
|
||||
<Header
|
||||
indexPatternName="name"
|
||||
|
@ -17,11 +17,11 @@ exports[`CreateIndexPatternWizard defaults to the loading state 1`] = `
|
|||
toastLifeTimeMs={6000}
|
||||
toasts={Array []}
|
||||
/>
|
||||
</React.Fragment>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
exports[`CreateIndexPatternWizard renders index pattern step when there are indices 1`] = `
|
||||
<React.Fragment>
|
||||
<Fragment>
|
||||
<div>
|
||||
<Header
|
||||
indexPatternName="name"
|
||||
|
@ -61,11 +61,11 @@ exports[`CreateIndexPatternWizard renders index pattern step when there are indi
|
|||
toastLifeTimeMs={6000}
|
||||
toasts={Array []}
|
||||
/>
|
||||
</React.Fragment>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
exports[`CreateIndexPatternWizard renders the empty state when there are no indices 1`] = `
|
||||
<React.Fragment>
|
||||
<Fragment>
|
||||
<div>
|
||||
<Header
|
||||
indexPatternName="name"
|
||||
|
@ -83,11 +83,11 @@ exports[`CreateIndexPatternWizard renders the empty state when there are no indi
|
|||
toastLifeTimeMs={6000}
|
||||
toasts={Array []}
|
||||
/>
|
||||
</React.Fragment>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
exports[`CreateIndexPatternWizard renders time field step when step is set to 2 1`] = `
|
||||
<React.Fragment>
|
||||
<Fragment>
|
||||
<div>
|
||||
<Header
|
||||
indexPatternName="name"
|
||||
|
@ -119,11 +119,11 @@ exports[`CreateIndexPatternWizard renders time field step when step is set to 2
|
|||
toastLifeTimeMs={6000}
|
||||
toasts={Array []}
|
||||
/>
|
||||
</React.Fragment>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
exports[`CreateIndexPatternWizard renders when there are no indices but there are remote clusters 1`] = `
|
||||
<React.Fragment>
|
||||
<Fragment>
|
||||
<div>
|
||||
<Header
|
||||
indexPatternName="name"
|
||||
|
@ -157,11 +157,11 @@ exports[`CreateIndexPatternWizard renders when there are no indices but there ar
|
|||
toastLifeTimeMs={6000}
|
||||
toasts={Array []}
|
||||
/>
|
||||
</React.Fragment>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
exports[`CreateIndexPatternWizard shows system indices even if there are no other indices if the include system indices is toggled 1`] = `
|
||||
<React.Fragment>
|
||||
<Fragment>
|
||||
<div>
|
||||
<Header
|
||||
indexPatternName="name"
|
||||
|
@ -201,5 +201,5 @@ exports[`CreateIndexPatternWizard shows system indices even if there are no othe
|
|||
toastLifeTimeMs={6000}
|
||||
toasts={Array []}
|
||||
/>
|
||||
</React.Fragment>
|
||||
</Fragment>
|
||||
`;
|
||||
|
|
|
@ -196,6 +196,6 @@ describe('CreateIndexPatternWizard', () => {
|
|||
expect(get).toBeCalled();
|
||||
expect(create).toBeCalled();
|
||||
expect(clear).toBeCalledWith('id');
|
||||
expect(changeUrl).toBeCalledWith(`/management/kibana/indices/id`);
|
||||
expect(changeUrl).toBeCalledWith(`/management/kibana/index_patterns/id`);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<kbn-management-app section="kibana/indices">
|
||||
<kbn-management-indices>
|
||||
<kbn-management-app section="kibana/index_patterns">
|
||||
<kbn-management-index-patterns>
|
||||
<div id="createIndexPatternReact"></div>
|
||||
</kbn-management-indices>
|
||||
</kbn-management-index-patterns>
|
||||
</kbn-management-app>
|
||||
|
|
|
@ -16,13 +16,11 @@ exports[`Header should render a different name, prompt, and beta tag if provided
|
|||
}
|
||||
}
|
||||
/>
|
||||
<React.Fragment>
|
||||
|
||||
<EuiBetaBadge
|
||||
label="Beta"
|
||||
tooltipPosition="top"
|
||||
/>
|
||||
</React.Fragment>
|
||||
|
||||
<EuiBetaBadge
|
||||
label="Beta"
|
||||
tooltipPosition="top"
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
<EuiFlexGroup
|
||||
|
@ -57,14 +55,12 @@ exports[`Header should render a different name, prompt, and beta tag if provided
|
|||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<React.Fragment>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
<div>
|
||||
Test prompt
|
||||
</div>
|
||||
</React.Fragment>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
<div>
|
||||
Test prompt
|
||||
</div>
|
||||
<EuiSpacer
|
||||
size="m"
|
||||
/>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
exports[`StatusMessage should render with exact matches 1`] = `
|
||||
<EuiText
|
||||
data-test-subj="createIndexPatternStatusMessage"
|
||||
grow={true}
|
||||
size="s"
|
||||
>
|
||||
|
@ -48,6 +49,7 @@ exports[`StatusMessage should render with exact matches 1`] = `
|
|||
|
||||
exports[`StatusMessage should render with no partial matches 1`] = `
|
||||
<EuiText
|
||||
data-test-subj="createIndexPatternStatusMessage"
|
||||
grow={true}
|
||||
size="s"
|
||||
>
|
||||
|
@ -83,6 +85,7 @@ exports[`StatusMessage should render with no partial matches 1`] = `
|
|||
|
||||
exports[`StatusMessage should render with partial matches 1`] = `
|
||||
<EuiText
|
||||
data-test-subj="createIndexPatternStatusMessage"
|
||||
grow={true}
|
||||
size="s"
|
||||
>
|
||||
|
@ -118,6 +121,7 @@ exports[`StatusMessage should render with partial matches 1`] = `
|
|||
|
||||
exports[`StatusMessage should render without a query 1`] = `
|
||||
<EuiText
|
||||
data-test-subj="createIndexPatternStatusMessage"
|
||||
grow={true}
|
||||
size="s"
|
||||
>
|
||||
|
@ -145,6 +149,7 @@ exports[`StatusMessage should render without a query 1`] = `
|
|||
|
||||
exports[`StatusMessage should show that no indices exist 1`] = `
|
||||
<EuiText
|
||||
data-test-subj="createIndexPatternStatusMessage"
|
||||
grow={true}
|
||||
size="s"
|
||||
>
|
||||
|
@ -165,6 +170,7 @@ exports[`StatusMessage should show that no indices exist 1`] = `
|
|||
|
||||
exports[`StatusMessage should show that system indices exist 1`] = `
|
||||
<EuiText
|
||||
data-test-subj="createIndexPatternStatusMessage"
|
||||
grow={true}
|
||||
size="s"
|
||||
>
|
||||
|
|
|
@ -161,7 +161,7 @@ export const StatusMessage = ({
|
|||
}
|
||||
|
||||
return (
|
||||
<EuiText size="s">
|
||||
<EuiText size="s" data-test-subj="createIndexPatternStatusMessage">
|
||||
<EuiTextColor color={statusColor}>
|
||||
{ statusIcon ? <EuiIcon type={statusIcon}/> : null }
|
||||
{statusMessage}
|
||||
|
|
|
@ -136,7 +136,7 @@ export class CreateIndexPatternWizard extends Component {
|
|||
}
|
||||
|
||||
services.indexPatterns.cache.clear(createdId);
|
||||
services.changeUrl(`/management/kibana/indices/${createdId}`);
|
||||
services.changeUrl(`/management/kibana/index_patterns/${createdId}`);
|
||||
}
|
||||
|
||||
goToTimeFieldStep = (indexPattern) => {
|
||||
|
|
|
@ -26,7 +26,7 @@ import { getCreateBreadcrumbs } from '../breadcrumbs';
|
|||
|
||||
import { renderCreateIndexPatternWizard, destroyCreateIndexPatternWizard } from './render';
|
||||
|
||||
uiRoutes.when('/management/kibana/index', {
|
||||
uiRoutes.when('/management/kibana/index_pattern', {
|
||||
template: angularTemplate,
|
||||
k7Breadcrumbs: getCreateBreadcrumbs,
|
||||
controller: function ($scope, $injector) {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<kbn-management-app section="kibana/indices">
|
||||
<kbn-management-indices>
|
||||
<kbn-management-app section="kibana/index_patterns">
|
||||
<kbn-management-index-patterns>
|
||||
<div class="kuiViewContent">
|
||||
<kbn-management-index-header
|
||||
<kbn-management-index-patterns-header
|
||||
index-pattern="fieldSettings.indexPattern"
|
||||
></kbn-management-index-header>
|
||||
></kbn-management-index-patterns-header>
|
||||
</div>
|
||||
|
||||
<div id="reactFieldEditor"></div>
|
||||
|
||||
</kbn-management-indices>
|
||||
</kbn-management-index-patterns>
|
||||
</kbn-management-app>
|
||||
|
|
|
@ -71,15 +71,15 @@ const destroyFieldEditor = () => {
|
|||
};
|
||||
|
||||
uiRoutes
|
||||
.when('/management/kibana/indices/:indexPatternId/field/:fieldName*', {
|
||||
.when('/management/kibana/index_patterns/:indexPatternId/field/:fieldName*', {
|
||||
mode: 'edit',
|
||||
k7Breadcrumbs: getEditFieldBreadcrumbs
|
||||
})
|
||||
.when('/management/kibana/indices/:indexPatternId/create-field/', {
|
||||
.when('/management/kibana/index_patterns/:indexPatternId/create-field/', {
|
||||
mode: 'create',
|
||||
k7Breadcrumbs: getCreateFieldBreadcrumbs
|
||||
})
|
||||
.defaults(/management\/kibana\/indices\/[^\/]+\/(field|create-field)(\/|$)/, {
|
||||
.defaults(/management\/kibana\/index_patterns\/[^\/]+\/(field|create-field)(\/|$)/, {
|
||||
template,
|
||||
mapBreadcrumbs($route, breadcrumbs) {
|
||||
const { indexPattern } = $route.current.locals;
|
||||
|
@ -97,7 +97,7 @@ uiRoutes
|
|||
resolve: {
|
||||
indexPattern: function ($route, redirectWhenMissing, indexPatterns) {
|
||||
return indexPatterns.get($route.current.params.indexPatternId)
|
||||
.catch(redirectWhenMissing('/management/kibana/indices'));
|
||||
.catch(redirectWhenMissing('/management/kibana/index_patterns'));
|
||||
}
|
||||
},
|
||||
controllerAs: 'fieldSettings',
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
<kbn-management-app section="kibana/indices" omit-breadcrumb-pages="['indices']">
|
||||
<kbn-management-indices>
|
||||
<kbn-management-app section="kibana/index_patterns" omit-breadcrumb-pages="['index_patterns']">
|
||||
<kbn-management-index-patterns>
|
||||
<div
|
||||
ng-controller="managementIndicesEdit"
|
||||
ng-controller="managementIndexPatternsEdit"
|
||||
data-test-subj="editIndexPattern"
|
||||
role="region"
|
||||
aria-label="{{::'kbn.management.editIndexPattern.detailsAria' | i18n: { defaultMessage: 'Index pattern details' } }}"
|
||||
>
|
||||
<!-- Header -->
|
||||
<kbn-management-index-header
|
||||
<kbn-management-index-patterns-header
|
||||
index-pattern="indexPattern"
|
||||
set-default="setDefaultPattern()"
|
||||
refresh-fields="refreshFields()"
|
||||
delete="removePattern()"
|
||||
></kbn-management-index-header>
|
||||
></kbn-management-index-patterns-header>
|
||||
|
||||
<div class="euiSpacer euiSpacer--s"></div>
|
||||
<p ng-if="::(indexPattern.timeFieldName || (indexPattern.tags && indexPattern.tags.length))">
|
||||
|
@ -178,5 +178,5 @@
|
|||
<div id="reactSourceFiltersTable"></div>
|
||||
</div>
|
||||
</div>
|
||||
</kbn-management-indices>
|
||||
</kbn-management-index-patterns>
|
||||
</kbn-management-app>
|
||||
|
|
|
@ -157,32 +157,32 @@ function destroyIndexedFieldsTable() {
|
|||
}
|
||||
|
||||
uiRoutes
|
||||
.when('/management/kibana/indices/:indexPatternId', {
|
||||
.when('/management/kibana/index_patterns/:indexPatternId', {
|
||||
template,
|
||||
k7Breadcrumbs: getEditBreadcrumbs,
|
||||
resolve: {
|
||||
indexPattern: function ($route, redirectWhenMissing, indexPatterns) {
|
||||
return indexPatterns
|
||||
.get($route.current.params.indexPatternId)
|
||||
.catch(redirectWhenMissing('/management/kibana/index'));
|
||||
.catch(redirectWhenMissing('/management/kibana/index_pattern'));
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
uiRoutes
|
||||
.when('/management/kibana/indices', {
|
||||
.when('/management/kibana/index_patterns', {
|
||||
redirectTo() {
|
||||
const defaultIndex = chrome.getUiSettingsClient().get('defaultIndex');
|
||||
if (defaultIndex) {
|
||||
return `/management/kibana/indices/${defaultIndex}`;
|
||||
return `/management/kibana/index_patterns/${defaultIndex}`;
|
||||
}
|
||||
|
||||
return '/management/kibana/index';
|
||||
return '/management/kibana/index_pattern';
|
||||
}
|
||||
});
|
||||
|
||||
uiModules.get('apps/management')
|
||||
.controller('managementIndicesEdit', function (
|
||||
.controller('managementIndexPatternsEdit', function (
|
||||
$scope, $location, $route, config, indexPatterns, Private, AppState, docTitle, confirmModal) {
|
||||
const $state = $scope.state = new AppState();
|
||||
const { fieldWildcardMatcher } = Private(FieldWildcardProvider);
|
||||
|
@ -275,7 +275,7 @@ uiModules.get('apps/management')
|
|||
|
||||
indexPatterns.delete($scope.indexPattern)
|
||||
.then(function () {
|
||||
$location.url('/management/kibana/index');
|
||||
$location.url('/management/kibana/index_patterns');
|
||||
})
|
||||
.catch(fatalError);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ import { uiModules } from 'ui/modules';
|
|||
import template from './index_header.html';
|
||||
uiModules
|
||||
.get('apps/management')
|
||||
.directive('kbnManagementIndexHeader', function (config) {
|
||||
.directive('kbnManagementIndexPatternsHeader', function (config) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template,
|
||||
|
|
|
@ -2,26 +2,24 @@
|
|||
|
||||
exports[`Table editing should show a save button 1`] = `
|
||||
<div>
|
||||
<React.Fragment>
|
||||
<EuiButtonIcon
|
||||
aria-label="Save"
|
||||
color="primary"
|
||||
iconSize="m"
|
||||
iconType="checkInCircleFilled"
|
||||
onClick={[Function]}
|
||||
size="s"
|
||||
type="button"
|
||||
/>
|
||||
<EuiButtonIcon
|
||||
aria-label="Cancel"
|
||||
color="primary"
|
||||
iconSize="m"
|
||||
iconType="cross"
|
||||
onClick={[Function]}
|
||||
size="s"
|
||||
type="button"
|
||||
/>
|
||||
</React.Fragment>
|
||||
<EuiButtonIcon
|
||||
aria-label="Save"
|
||||
color="primary"
|
||||
iconSize="m"
|
||||
iconType="checkInCircleFilled"
|
||||
onClick={[Function]}
|
||||
size="s"
|
||||
type="button"
|
||||
/>
|
||||
<EuiButtonIcon
|
||||
aria-label="Cancel"
|
||||
color="primary"
|
||||
iconSize="m"
|
||||
iconType="cross"
|
||||
onClick={[Function]}
|
||||
size="s"
|
||||
type="button"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
|
|
|
@ -78,13 +78,13 @@ const indexPatternsResolutions = {
|
|||
|
||||
// add a dependency to all of the subsection routes
|
||||
uiRoutes
|
||||
.defaults(/management\/kibana\/(indices|index)/, {
|
||||
.defaults(/management\/kibana\/(index_patterns|index_pattern)/, {
|
||||
resolve: indexPatternsResolutions
|
||||
});
|
||||
|
||||
// wrapper directive, which sets some global stuff up like the left nav
|
||||
uiModules.get('apps/management')
|
||||
.directive('kbnManagementIndices', function ($route, config, kbnUrl, Private) {
|
||||
.directive('kbnManagementIndexPatterns', function ($route, config, kbnUrl, Private) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
transclude: true,
|
||||
|
@ -104,7 +104,7 @@ uiModules.get('apps/management')
|
|||
return {
|
||||
id: id,
|
||||
title: pattern.get('title'),
|
||||
url: kbnUrl.eval('#/management/kibana/indices/{{id}}', { id: id }),
|
||||
url: kbnUrl.eval('#/management/kibana/index_patterns/{{id}}', { id: id }),
|
||||
active: $scope.editingId === id,
|
||||
default: $scope.defaultIndex === id,
|
||||
tag: tags && tags.length ? tags[0] : null,
|
||||
|
@ -137,10 +137,10 @@ uiModules.get('apps/management')
|
|||
};
|
||||
});
|
||||
|
||||
management.getSection('kibana').register('indices', {
|
||||
management.getSection('kibana').register('index_patterns', {
|
||||
display: i18n.translate('kbn.management.indexPattern.sectionsHeader', { defaultMessage: 'Index Patterns' }),
|
||||
order: 0,
|
||||
url: '#/management/kibana/indices/'
|
||||
url: '#/management/kibana/index_patterns/'
|
||||
});
|
||||
|
||||
FeatureCatalogueRegistryProvider.register(() => {
|
||||
|
@ -150,7 +150,7 @@ FeatureCatalogueRegistryProvider.register(() => {
|
|||
description: i18n.translate('kbn.management.indexPatternLabel',
|
||||
{ defaultMessage: 'Manage the index patterns that help retrieve your data from Elasticsearch.' }),
|
||||
icon: 'indexPatternApp',
|
||||
path: '/app/kibana#/management/kibana/indices',
|
||||
path: '/app/kibana#/management/kibana/index_patterns',
|
||||
showOnHomePage: true,
|
||||
category: FeatureCatalogueCategory.ADMIN
|
||||
};
|
||||
|
|
|
@ -24,45 +24,43 @@ exports[`Flyout conflicts should allow conflict resolution 1`] = `
|
|||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<React.Fragment>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
<EuiCallOut
|
||||
color="warning"
|
||||
iconType="help"
|
||||
size="m"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Index Pattern Conflicts"
|
||||
id="kbn.management.objects.objectsTable.flyout.indexPatternConflictsTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="The following saved objects use index patterns that do not exist. Please select the index patterns you'd like re-associated with them. You can {indexPatternLink} if necessary."
|
||||
id="kbn.management.objects.objectsTable.flyout.indexPatternConflictsDescription"
|
||||
values={
|
||||
Object {
|
||||
"indexPatternLink": <EuiLink
|
||||
color="primary"
|
||||
href=""
|
||||
type="button"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="create a new index pattern"
|
||||
id="kbn.management.objects.objectsTable.flyout.indexPatternConflictsCalloutLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
}
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
<EuiCallOut
|
||||
color="warning"
|
||||
iconType="help"
|
||||
size="m"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Index Pattern Conflicts"
|
||||
id="kbn.management.objects.objectsTable.flyout.indexPatternConflictsTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="The following saved objects use index patterns that do not exist. Please select the index patterns you'd like re-associated with them. You can {indexPatternLink} if necessary."
|
||||
id="kbn.management.objects.objectsTable.flyout.indexPatternConflictsDescription"
|
||||
values={
|
||||
Object {
|
||||
"indexPatternLink": <EuiLink
|
||||
color="primary"
|
||||
href=""
|
||||
type="button"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="create a new index pattern"
|
||||
id="kbn.management.objects.objectsTable.flyout.indexPatternConflictsCalloutLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
</React.Fragment>
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
</EuiFlyoutHeader>
|
||||
<EuiFlyoutBody>
|
||||
<EuiInMemoryTable
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Header should render normally 1`] = `
|
||||
<React.Fragment>
|
||||
<Fragment>
|
||||
<EuiFlexGroup
|
||||
alignItems="baseline"
|
||||
component="div"
|
||||
|
@ -130,5 +130,5 @@ exports[`Header should render normally 1`] = `
|
|||
<EuiSpacer
|
||||
size="m"
|
||||
/>
|
||||
</React.Fragment>
|
||||
</Fragment>
|
||||
`;
|
||||
|
|
|
@ -40,77 +40,73 @@ exports[`Relationships should render dashboards normally 1`] = `
|
|||
textStyle="normal"
|
||||
type="row"
|
||||
>
|
||||
<React.Fragment
|
||||
key="visualizations"
|
||||
<EuiDescriptionListTitle
|
||||
style={
|
||||
Object {
|
||||
"marginBottom": "1rem",
|
||||
}
|
||||
}
|
||||
>
|
||||
<EuiDescriptionListTitle
|
||||
style={
|
||||
Object {
|
||||
"marginBottom": "1rem",
|
||||
}
|
||||
<EuiCallOut
|
||||
color="success"
|
||||
size="m"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Dashboard"
|
||||
id="kbn.management.objects.objectsTable.relationships.dashboard.calloutTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<EuiCallOut
|
||||
color="success"
|
||||
size="m"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Dashboard"
|
||||
id="kbn.management.objects.objectsTable.relationships.dashboard.calloutTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="Here are some visualizations used on this dashboard. You can safely delete this dashboard and the visualizations will still work properly."
|
||||
id="kbn.management.objects.objectsTable.relationships.dashboard.calloutText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
</EuiDescriptionListTitle>
|
||||
<EuiInMemoryTable
|
||||
columns={
|
||||
Array [
|
||||
Object {
|
||||
"render": [Function],
|
||||
"width": 24,
|
||||
},
|
||||
Object {
|
||||
"field": "title",
|
||||
"name": "Title",
|
||||
"render": [Function],
|
||||
},
|
||||
Object {
|
||||
"actions": Array [
|
||||
Object {
|
||||
"description": "View this saved object within Kibana",
|
||||
"icon": "eye",
|
||||
"name": "In app",
|
||||
"onClick": [Function],
|
||||
},
|
||||
],
|
||||
"name": "Actions",
|
||||
},
|
||||
]
|
||||
}
|
||||
executeQueryOptions={Object {}}
|
||||
items={
|
||||
Array [
|
||||
Object {
|
||||
"id": "1",
|
||||
},
|
||||
Object {
|
||||
"id": "2",
|
||||
},
|
||||
]
|
||||
}
|
||||
pagination={true}
|
||||
responsive={true}
|
||||
sorting={false}
|
||||
/>
|
||||
</React.Fragment>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="Here are some visualizations used on this dashboard. You can safely delete this dashboard and the visualizations will still work properly."
|
||||
id="kbn.management.objects.objectsTable.relationships.dashboard.calloutText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
</EuiDescriptionListTitle>
|
||||
<EuiInMemoryTable
|
||||
columns={
|
||||
Array [
|
||||
Object {
|
||||
"render": [Function],
|
||||
"width": 24,
|
||||
},
|
||||
Object {
|
||||
"field": "title",
|
||||
"name": "Title",
|
||||
"render": [Function],
|
||||
},
|
||||
Object {
|
||||
"actions": Array [
|
||||
Object {
|
||||
"description": "View this saved object within Kibana",
|
||||
"icon": "eye",
|
||||
"name": "In app",
|
||||
"onClick": [Function],
|
||||
},
|
||||
],
|
||||
"name": "Actions",
|
||||
},
|
||||
]
|
||||
}
|
||||
executeQueryOptions={Object {}}
|
||||
items={
|
||||
Array [
|
||||
Object {
|
||||
"id": "1",
|
||||
},
|
||||
Object {
|
||||
"id": "2",
|
||||
},
|
||||
]
|
||||
}
|
||||
pagination={true}
|
||||
responsive={true}
|
||||
sorting={false}
|
||||
/>
|
||||
</EuiDescriptionList>
|
||||
</EuiFlyoutBody>
|
||||
</EuiFlyout>
|
||||
|
@ -248,142 +244,134 @@ exports[`Relationships should render searches normally 1`] = `
|
|||
textStyle="normal"
|
||||
type="row"
|
||||
>
|
||||
<React.Fragment
|
||||
key="indexPatterns"
|
||||
<EuiDescriptionListTitle
|
||||
style={
|
||||
Object {
|
||||
"marginBottom": "1rem",
|
||||
}
|
||||
}
|
||||
>
|
||||
<EuiDescriptionListTitle
|
||||
style={
|
||||
Object {
|
||||
"marginBottom": "1rem",
|
||||
}
|
||||
<EuiCallOut
|
||||
color="success"
|
||||
size="m"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Saved Search"
|
||||
id="kbn.management.objects.objectsTable.relationships.search.calloutTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<EuiCallOut
|
||||
color="success"
|
||||
size="m"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Saved Search"
|
||||
id="kbn.management.objects.objectsTable.relationships.search.calloutTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="Here is the index pattern tied to this saved search."
|
||||
id="kbn.management.objects.objectsTable.relationships.search.calloutText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
</EuiDescriptionListTitle>
|
||||
<EuiInMemoryTable
|
||||
columns={
|
||||
Array [
|
||||
Object {
|
||||
"render": [Function],
|
||||
"width": 24,
|
||||
},
|
||||
Object {
|
||||
"field": "title",
|
||||
"name": "Title",
|
||||
"render": [Function],
|
||||
},
|
||||
Object {
|
||||
"actions": Array [
|
||||
Object {
|
||||
"description": "View this saved object within Kibana",
|
||||
"icon": "eye",
|
||||
"name": "In app",
|
||||
"onClick": [Function],
|
||||
},
|
||||
],
|
||||
"name": "Actions",
|
||||
},
|
||||
]
|
||||
}
|
||||
executeQueryOptions={Object {}}
|
||||
items={
|
||||
Array [
|
||||
Object {
|
||||
"id": "1",
|
||||
},
|
||||
]
|
||||
}
|
||||
pagination={true}
|
||||
responsive={true}
|
||||
sorting={false}
|
||||
/>
|
||||
</React.Fragment>
|
||||
<React.Fragment
|
||||
key="visualizations"
|
||||
>
|
||||
<EuiDescriptionListTitle
|
||||
style={
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="Here is the index pattern tied to this saved search."
|
||||
id="kbn.management.objects.objectsTable.relationships.search.calloutText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
</EuiDescriptionListTitle>
|
||||
<EuiInMemoryTable
|
||||
columns={
|
||||
Array [
|
||||
Object {
|
||||
"marginBottom": "1rem",
|
||||
}
|
||||
"render": [Function],
|
||||
"width": 24,
|
||||
},
|
||||
Object {
|
||||
"field": "title",
|
||||
"name": "Title",
|
||||
"render": [Function],
|
||||
},
|
||||
Object {
|
||||
"actions": Array [
|
||||
Object {
|
||||
"description": "View this saved object within Kibana",
|
||||
"icon": "eye",
|
||||
"name": "In app",
|
||||
"onClick": [Function],
|
||||
},
|
||||
],
|
||||
"name": "Actions",
|
||||
},
|
||||
]
|
||||
}
|
||||
executeQueryOptions={Object {}}
|
||||
items={
|
||||
Array [
|
||||
Object {
|
||||
"id": "1",
|
||||
},
|
||||
]
|
||||
}
|
||||
pagination={true}
|
||||
responsive={true}
|
||||
sorting={false}
|
||||
/>
|
||||
<EuiDescriptionListTitle
|
||||
style={
|
||||
Object {
|
||||
"marginBottom": "1rem",
|
||||
}
|
||||
}
|
||||
>
|
||||
<EuiCallOut
|
||||
color="warning"
|
||||
size="m"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Warning"
|
||||
id="kbn.management.objects.objectsTable.relationships.warningTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<EuiCallOut
|
||||
color="warning"
|
||||
size="m"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Warning"
|
||||
id="kbn.management.objects.objectsTable.relationships.warningTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="Here are some visualizations that use this saved search. If you delete this saved search, these visualizations will not longer work properly."
|
||||
id="kbn.management.objects.objectsTable.relationships.search.visualizations.calloutText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
</EuiDescriptionListTitle>
|
||||
<EuiInMemoryTable
|
||||
columns={
|
||||
Array [
|
||||
Object {
|
||||
"render": [Function],
|
||||
"width": 24,
|
||||
},
|
||||
Object {
|
||||
"field": "title",
|
||||
"name": "Title",
|
||||
"render": [Function],
|
||||
},
|
||||
Object {
|
||||
"actions": Array [
|
||||
Object {
|
||||
"description": "View this saved object within Kibana",
|
||||
"icon": "eye",
|
||||
"name": "In app",
|
||||
"onClick": [Function],
|
||||
},
|
||||
],
|
||||
"name": "Actions",
|
||||
},
|
||||
]
|
||||
}
|
||||
executeQueryOptions={Object {}}
|
||||
items={
|
||||
Array [
|
||||
Object {
|
||||
"id": "2",
|
||||
},
|
||||
]
|
||||
}
|
||||
pagination={true}
|
||||
responsive={true}
|
||||
sorting={false}
|
||||
/>
|
||||
</React.Fragment>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="Here are some visualizations that use this saved search. If you delete this saved search, these visualizations will not longer work properly."
|
||||
id="kbn.management.objects.objectsTable.relationships.search.visualizations.calloutText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
</EuiDescriptionListTitle>
|
||||
<EuiInMemoryTable
|
||||
columns={
|
||||
Array [
|
||||
Object {
|
||||
"render": [Function],
|
||||
"width": 24,
|
||||
},
|
||||
Object {
|
||||
"field": "title",
|
||||
"name": "Title",
|
||||
"render": [Function],
|
||||
},
|
||||
Object {
|
||||
"actions": Array [
|
||||
Object {
|
||||
"description": "View this saved object within Kibana",
|
||||
"icon": "eye",
|
||||
"name": "In app",
|
||||
"onClick": [Function],
|
||||
},
|
||||
],
|
||||
"name": "Actions",
|
||||
},
|
||||
]
|
||||
}
|
||||
executeQueryOptions={Object {}}
|
||||
items={
|
||||
Array [
|
||||
Object {
|
||||
"id": "2",
|
||||
},
|
||||
]
|
||||
}
|
||||
pagination={true}
|
||||
responsive={true}
|
||||
sorting={false}
|
||||
/>
|
||||
</EuiDescriptionList>
|
||||
</EuiFlyoutBody>
|
||||
</EuiFlyout>
|
||||
|
@ -429,77 +417,73 @@ exports[`Relationships should render visualizations normally 1`] = `
|
|||
textStyle="normal"
|
||||
type="row"
|
||||
>
|
||||
<React.Fragment
|
||||
key="dashboards"
|
||||
<EuiDescriptionListTitle
|
||||
style={
|
||||
Object {
|
||||
"marginBottom": "1rem",
|
||||
}
|
||||
}
|
||||
>
|
||||
<EuiDescriptionListTitle
|
||||
style={
|
||||
Object {
|
||||
"marginBottom": "1rem",
|
||||
}
|
||||
<EuiCallOut
|
||||
color="warning"
|
||||
size="m"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Warning"
|
||||
id="kbn.management.objects.objectsTable.relationships.warningTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<EuiCallOut
|
||||
color="warning"
|
||||
size="m"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Warning"
|
||||
id="kbn.management.objects.objectsTable.relationships.warningTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="Here are some dashboards which contain this visualization. If you delete this visualization, these dashboards will no longer show them."
|
||||
id="kbn.management.objects.objectsTable.relationships.visualization.calloutText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
</EuiDescriptionListTitle>
|
||||
<EuiInMemoryTable
|
||||
columns={
|
||||
Array [
|
||||
Object {
|
||||
"render": [Function],
|
||||
"width": 24,
|
||||
},
|
||||
Object {
|
||||
"field": "title",
|
||||
"name": "Title",
|
||||
"render": [Function],
|
||||
},
|
||||
Object {
|
||||
"actions": Array [
|
||||
Object {
|
||||
"description": "View this saved object within Kibana",
|
||||
"icon": "eye",
|
||||
"name": "In app",
|
||||
"onClick": [Function],
|
||||
},
|
||||
],
|
||||
"name": "Actions",
|
||||
},
|
||||
]
|
||||
}
|
||||
executeQueryOptions={Object {}}
|
||||
items={
|
||||
Array [
|
||||
Object {
|
||||
"id": "1",
|
||||
},
|
||||
Object {
|
||||
"id": "2",
|
||||
},
|
||||
]
|
||||
}
|
||||
pagination={true}
|
||||
responsive={true}
|
||||
sorting={false}
|
||||
/>
|
||||
</React.Fragment>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="Here are some dashboards which contain this visualization. If you delete this visualization, these dashboards will no longer show them."
|
||||
id="kbn.management.objects.objectsTable.relationships.visualization.calloutText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
</EuiDescriptionListTitle>
|
||||
<EuiInMemoryTable
|
||||
columns={
|
||||
Array [
|
||||
Object {
|
||||
"render": [Function],
|
||||
"width": 24,
|
||||
},
|
||||
Object {
|
||||
"field": "title",
|
||||
"name": "Title",
|
||||
"render": [Function],
|
||||
},
|
||||
Object {
|
||||
"actions": Array [
|
||||
Object {
|
||||
"description": "View this saved object within Kibana",
|
||||
"icon": "eye",
|
||||
"name": "In app",
|
||||
"onClick": [Function],
|
||||
},
|
||||
],
|
||||
"name": "Actions",
|
||||
},
|
||||
]
|
||||
}
|
||||
executeQueryOptions={Object {}}
|
||||
items={
|
||||
Array [
|
||||
Object {
|
||||
"id": "1",
|
||||
},
|
||||
Object {
|
||||
"id": "2",
|
||||
},
|
||||
]
|
||||
}
|
||||
pagination={true}
|
||||
responsive={true}
|
||||
sorting={false}
|
||||
/>
|
||||
</EuiDescriptionList>
|
||||
</EuiFlyoutBody>
|
||||
</EuiFlyout>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Table should render normally 1`] = `
|
||||
<React.Fragment>
|
||||
<Fragment>
|
||||
<EuiSearchBar
|
||||
box={
|
||||
Object {
|
||||
|
@ -136,5 +136,5 @@ exports[`Table should render normally 1`] = `
|
|||
}
|
||||
/>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
</Fragment>
|
||||
`;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Form should not render no settings message when instructed not to 1`] = `<React.Fragment />`;
|
||||
exports[`Form should not render no settings message when instructed not to 1`] = `<Fragment />`;
|
||||
|
||||
exports[`Form should render no settings message when there are no settings 1`] = `
|
||||
<React.Fragment>
|
||||
<Fragment>
|
||||
<EuiPanel
|
||||
grow={true}
|
||||
hasShadow={false}
|
||||
|
@ -29,225 +29,213 @@ exports[`Form should render no settings message when there are no settings 1`] =
|
|||
}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</React.Fragment>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
exports[`Form should render normally 1`] = `
|
||||
<React.Fragment>
|
||||
<React.Fragment
|
||||
key="general"
|
||||
<Fragment>
|
||||
<EuiPanel
|
||||
grow={true}
|
||||
hasShadow={false}
|
||||
paddingSize="l"
|
||||
>
|
||||
<EuiPanel
|
||||
grow={true}
|
||||
hasShadow={false}
|
||||
paddingSize="l"
|
||||
>
|
||||
<EuiForm>
|
||||
<EuiText
|
||||
grow={true}
|
||||
size="m"
|
||||
<EuiForm>
|
||||
<EuiText
|
||||
grow={true}
|
||||
size="m"
|
||||
>
|
||||
<EuiFlexGroup
|
||||
alignItems="baseline"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="l"
|
||||
justifyContent="flexStart"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
>
|
||||
<EuiFlexGroup
|
||||
alignItems="baseline"
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="l"
|
||||
justifyContent="flexStart"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
grow={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<h2>
|
||||
General
|
||||
</h2>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiText>
|
||||
<EuiSpacer
|
||||
size="m"
|
||||
/>
|
||||
<Field
|
||||
clear={[Function]}
|
||||
key="general:test:date"
|
||||
save={[Function]}
|
||||
setting={
|
||||
Object {
|
||||
"ariaName": "general test date",
|
||||
"category": Array [
|
||||
"general",
|
||||
],
|
||||
"description": "bar",
|
||||
"displayName": "Test date",
|
||||
"name": "general:test:date",
|
||||
}
|
||||
<h2>
|
||||
General
|
||||
</h2>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiText>
|
||||
<EuiSpacer
|
||||
size="m"
|
||||
/>
|
||||
<Field
|
||||
clear={[Function]}
|
||||
key="general:test:date"
|
||||
save={[Function]}
|
||||
setting={
|
||||
Object {
|
||||
"ariaName": "general test date",
|
||||
"category": Array [
|
||||
"general",
|
||||
],
|
||||
"description": "bar",
|
||||
"displayName": "Test date",
|
||||
"name": "general:test:date",
|
||||
}
|
||||
/>
|
||||
<Field
|
||||
clear={[Function]}
|
||||
key="setting:test"
|
||||
save={[Function]}
|
||||
setting={
|
||||
Object {
|
||||
"ariaName": "setting test",
|
||||
"category": Array [
|
||||
"general",
|
||||
],
|
||||
"description": "foo",
|
||||
"displayName": "Test setting",
|
||||
"name": "setting:test",
|
||||
}
|
||||
}
|
||||
/>
|
||||
<Field
|
||||
clear={[Function]}
|
||||
key="setting:test"
|
||||
save={[Function]}
|
||||
setting={
|
||||
Object {
|
||||
"ariaName": "setting test",
|
||||
"category": Array [
|
||||
"general",
|
||||
],
|
||||
"description": "foo",
|
||||
"displayName": "Test setting",
|
||||
"name": "setting:test",
|
||||
}
|
||||
/>
|
||||
</EuiForm>
|
||||
</EuiPanel>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
</React.Fragment>
|
||||
<React.Fragment
|
||||
key="dashboard"
|
||||
}
|
||||
/>
|
||||
</EuiForm>
|
||||
</EuiPanel>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
<EuiPanel
|
||||
grow={true}
|
||||
hasShadow={false}
|
||||
paddingSize="l"
|
||||
>
|
||||
<EuiPanel
|
||||
grow={true}
|
||||
hasShadow={false}
|
||||
paddingSize="l"
|
||||
>
|
||||
<EuiForm>
|
||||
<EuiText
|
||||
grow={true}
|
||||
size="m"
|
||||
<EuiForm>
|
||||
<EuiText
|
||||
grow={true}
|
||||
size="m"
|
||||
>
|
||||
<EuiFlexGroup
|
||||
alignItems="baseline"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="l"
|
||||
justifyContent="flexStart"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
>
|
||||
<EuiFlexGroup
|
||||
alignItems="baseline"
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="l"
|
||||
justifyContent="flexStart"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
grow={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<h2>
|
||||
Dashboard
|
||||
</h2>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiText>
|
||||
<EuiSpacer
|
||||
size="m"
|
||||
/>
|
||||
<Field
|
||||
clear={[Function]}
|
||||
key="dashboard:test:setting"
|
||||
save={[Function]}
|
||||
setting={
|
||||
Object {
|
||||
"ariaName": "dashboard test setting",
|
||||
"category": Array [
|
||||
"dashboard",
|
||||
],
|
||||
"displayName": "Dashboard test setting",
|
||||
"name": "dashboard:test:setting",
|
||||
}
|
||||
<h2>
|
||||
Dashboard
|
||||
</h2>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiText>
|
||||
<EuiSpacer
|
||||
size="m"
|
||||
/>
|
||||
<Field
|
||||
clear={[Function]}
|
||||
key="dashboard:test:setting"
|
||||
save={[Function]}
|
||||
setting={
|
||||
Object {
|
||||
"ariaName": "dashboard test setting",
|
||||
"category": Array [
|
||||
"dashboard",
|
||||
],
|
||||
"displayName": "Dashboard test setting",
|
||||
"name": "dashboard:test:setting",
|
||||
}
|
||||
/>
|
||||
</EuiForm>
|
||||
</EuiPanel>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
</React.Fragment>
|
||||
<React.Fragment
|
||||
key="x-pack"
|
||||
}
|
||||
/>
|
||||
</EuiForm>
|
||||
</EuiPanel>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
<EuiPanel
|
||||
grow={true}
|
||||
hasShadow={false}
|
||||
paddingSize="l"
|
||||
>
|
||||
<EuiPanel
|
||||
grow={true}
|
||||
hasShadow={false}
|
||||
paddingSize="l"
|
||||
>
|
||||
<EuiForm>
|
||||
<EuiText
|
||||
grow={true}
|
||||
size="m"
|
||||
<EuiForm>
|
||||
<EuiText
|
||||
grow={true}
|
||||
size="m"
|
||||
>
|
||||
<EuiFlexGroup
|
||||
alignItems="baseline"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="l"
|
||||
justifyContent="flexStart"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
>
|
||||
<EuiFlexGroup
|
||||
alignItems="baseline"
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="l"
|
||||
justifyContent="flexStart"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
grow={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<h2>
|
||||
X-pack
|
||||
</h2>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<em>
|
||||
<FormattedMessage
|
||||
defaultMessage="Search terms are hiding {settingsCount} settings {clearSearch}"
|
||||
id="kbn.management.settings.form.searchResultText"
|
||||
values={
|
||||
Object {
|
||||
"clearSearch": <EuiLink
|
||||
color="primary"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<em>
|
||||
<FormattedMessage
|
||||
defaultMessage="(clear search)"
|
||||
id="kbn.management.settings.form.clearSearchResultText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</em>
|
||||
</EuiLink>,
|
||||
"settingsCount": 9,
|
||||
}
|
||||
<h2>
|
||||
X-pack
|
||||
</h2>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<em>
|
||||
<FormattedMessage
|
||||
defaultMessage="Search terms are hiding {settingsCount} settings {clearSearch}"
|
||||
id="kbn.management.settings.form.searchResultText"
|
||||
values={
|
||||
Object {
|
||||
"clearSearch": <EuiLink
|
||||
color="primary"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<em>
|
||||
<FormattedMessage
|
||||
defaultMessage="(clear search)"
|
||||
id="kbn.management.settings.form.clearSearchResultText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</em>
|
||||
</EuiLink>,
|
||||
"settingsCount": 9,
|
||||
}
|
||||
/>
|
||||
</em>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiText>
|
||||
<EuiSpacer
|
||||
size="m"
|
||||
/>
|
||||
<Field
|
||||
clear={[Function]}
|
||||
key="xpack:test:setting"
|
||||
save={[Function]}
|
||||
setting={
|
||||
Object {
|
||||
"ariaName": "xpack test setting",
|
||||
"category": Array [
|
||||
"x-pack",
|
||||
],
|
||||
"description": "bar",
|
||||
"displayName": "X-Pack test setting",
|
||||
"name": "xpack:test:setting",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</em>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiText>
|
||||
<EuiSpacer
|
||||
size="m"
|
||||
/>
|
||||
<Field
|
||||
clear={[Function]}
|
||||
key="xpack:test:setting"
|
||||
save={[Function]}
|
||||
setting={
|
||||
Object {
|
||||
"ariaName": "xpack test setting",
|
||||
"category": Array [
|
||||
"x-pack",
|
||||
],
|
||||
"description": "bar",
|
||||
"displayName": "X-Pack test setting",
|
||||
"name": "xpack:test:setting",
|
||||
}
|
||||
/>
|
||||
</EuiForm>
|
||||
</EuiPanel>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
</React.Fragment>
|
||||
</React.Fragment>
|
||||
}
|
||||
/>
|
||||
</EuiForm>
|
||||
</EuiPanel>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
</Fragment>
|
||||
`;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Search should render normally 1`] = `
|
||||
<React.Fragment>
|
||||
<Fragment>
|
||||
<EuiSearchBar
|
||||
box={
|
||||
Object {
|
||||
|
@ -57,5 +57,5 @@ exports[`Search should render normally 1`] = `
|
|||
}
|
||||
}
|
||||
/>
|
||||
</React.Fragment>
|
||||
</Fragment>
|
||||
`;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -91,7 +91,7 @@ export function onPremInstructions(apmIndexPattern) {
|
|||
bool: {
|
||||
filter: {
|
||||
exists: {
|
||||
field: 'listening',
|
||||
field: 'observer.listening',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -65,8 +65,8 @@ var apm = require('elastic-apm-node').start({curlyOpen}
|
|||
defaultMessage: 'See [the documentation]({documentationLink}) for advanced usage, including how to use with \
|
||||
[Babel/ES Modules]({babelEsModulesLink}).',
|
||||
values: {
|
||||
documentationLink: '{config.docs.base_url}guide/en/apm/agent/nodejs/1.x/index.html',
|
||||
babelEsModulesLink: '{config.docs.base_url}guide/en/apm/agent/nodejs/1.x/advanced-setup.html#es-modules',
|
||||
documentationLink: '{config.docs.base_url}guide/en/apm/agent/nodejs/current/index.html',
|
||||
babelEsModulesLink: '{config.docs.base_url}guide/en/apm/agent/nodejs/current/advanced-setup.html#es-modules',
|
||||
},
|
||||
}),
|
||||
},
|
||||
|
@ -128,7 +128,7 @@ MIDDLEWARE = (
|
|||
)`.split('\n'),
|
||||
textPost: i18n.translate('kbn.server.tutorials.apm.djangoClient.configure.textPost', {
|
||||
defaultMessage: 'See the [documentation]({documentationLink}) for advanced usage.',
|
||||
values: { documentationLink: '{config.docs.base_url}guide/en/apm/agent/python/2.x/django-support.html' },
|
||||
values: { documentationLink: '{config.docs.base_url}guide/en/apm/agent/python/current/django-support.html' },
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
@ -186,7 +186,7 @@ app.config['ELASTIC_APM'] = {curlyOpen}
|
|||
apm = ElasticAPM(app)`.split('\n'),
|
||||
textPost: i18n.translate('kbn.server.tutorials.apm.flaskClient.configure.textPost', {
|
||||
defaultMessage: 'See the [documentation]({documentationLink}) for advanced usage.',
|
||||
values: { documentationLink: '{config.docs.base_url}guide/en/apm/agent/python/2.x/flask-support.html' },
|
||||
values: { documentationLink: '{config.docs.base_url}guide/en/apm/agent/python/current/flask-support.html' },
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
@ -222,7 +222,7 @@ export const createRailsAgentInstructions = (apmServerUrl = '', secretToken = ''
|
|||
# server_url: '${apmServerUrl || 'http://localhost:8200'}'`.split('\n'),
|
||||
textPost: i18n.translate('kbn.server.tutorials.apm.railsClient.configure.textPost', {
|
||||
defaultMessage: 'See the [documentation]({documentationLink}) for configuration options and advanced usage.\n\n',
|
||||
values: { documentationLink: '{config.docs.base_url}guide/en/apm/agent/ruby/1.x/index.html' },
|
||||
values: { documentationLink: '{config.docs.base_url}guide/en/apm/agent/ruby/current/index.html' },
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
@ -296,7 +296,7 @@ export const createRackAgentInstructions = (apmServerUrl = '', secretToken = '')
|
|||
# server_url: '${apmServerUrl || 'http://localhost:8200'}'`.split('\n'),
|
||||
textPost: i18n.translate('kbn.server.tutorials.apm.rackClient.createConfig.textPost', {
|
||||
defaultMessage: 'See the [documentation]({documentationLink}) for configuration options and advanced usage.\n\n',
|
||||
values: { documentationLink: '{config.docs.base_url}guide/en/apm/agent/ruby/1.x/index.html' },
|
||||
values: { documentationLink: '{config.docs.base_url}guide/en/apm/agent/ruby/current/index.html' },
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
|
|
@ -17,9 +17,13 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { TUTORIAL_CATEGORY } from '../../../common/tutorials/tutorial_category';
|
||||
import { onPremInstructions, cloudInstructions, onPremCloudInstructions } from '../../../common/tutorials/heartbeat_instructions';
|
||||
import {
|
||||
onPremInstructions,
|
||||
cloudInstructions,
|
||||
onPremCloudInstructions,
|
||||
} from '../../../common/tutorials/heartbeat_instructions';
|
||||
|
||||
export function uptimeMonitorsSpecProvider(server, context) {
|
||||
return {
|
||||
|
@ -32,7 +36,8 @@ export function uptimeMonitorsSpecProvider(server, context) {
|
|||
defaultMessage: 'Monitor services for their availability',
|
||||
}),
|
||||
longDescription: i18n.translate('kbn.server.tutorials.uptimeMonitors.longDescription', {
|
||||
defaultMessage: 'Monitor services for their availability with active probing. \
|
||||
defaultMessage:
|
||||
'Monitor services for their availability with active probing. \
|
||||
Given a list of URLs, Heartbeat asks the simple question: Are you alive? \
|
||||
[Learn more]({learnMoreLink}).',
|
||||
values: {
|
||||
|
@ -41,23 +46,24 @@ export function uptimeMonitorsSpecProvider(server, context) {
|
|||
}),
|
||||
euiIconType: 'heartbeatApp',
|
||||
artifacts: {
|
||||
dashboards: [
|
||||
{
|
||||
id: 'f3e771c0-eb19-11e6-be20-559646f8b9ba',
|
||||
linkLabel: i18n.translate('kbn.server.tutorials.uptimeMonitors.artifacts.dashboards.linkLabel', {
|
||||
defaultMessage: 'Heartbeat dashboard',
|
||||
}),
|
||||
isOverview: true
|
||||
}
|
||||
],
|
||||
dashboards: [],
|
||||
application: {
|
||||
path: '/app/uptime',
|
||||
label: i18n.translate(
|
||||
'kbn.server.tutorials.uptimeMonitors.artifacts.dashboards.linkLabel',
|
||||
{
|
||||
defaultMessage: 'Uptime App',
|
||||
}
|
||||
),
|
||||
},
|
||||
exportedFields: {
|
||||
documentationUrl: '{config.docs.beats.heartbeat}/exported-fields.html'
|
||||
}
|
||||
documentationUrl: '{config.docs.beats.heartbeat}/exported-fields.html',
|
||||
},
|
||||
},
|
||||
completionTimeMinutes: 10,
|
||||
previewImagePath: '/plugins/kibana/home/tutorial_resources/uptime_monitors/screenshot.png',
|
||||
onPrem: onPremInstructions(null, null, null, context),
|
||||
elasticCloud: cloudInstructions(),
|
||||
onPremElasticCloud: onPremCloudInstructions()
|
||||
onPremElasticCloud: onPremCloudInstructions(),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -823,16 +823,6 @@ export function getUiSettingDefaults() {
|
|||
},
|
||||
}),
|
||||
},
|
||||
'dashboard:defaultDarkTheme': {
|
||||
name: i18n.translate('kbn.advancedSettings.dashboardDarkThemeTitle', {
|
||||
defaultMessage: 'Dark theme',
|
||||
}),
|
||||
value: false,
|
||||
description: i18n.translate('kbn.advancedSettings.dashboardDarkThemeText', {
|
||||
defaultMessage: 'New dashboards use dark theme by default',
|
||||
}),
|
||||
category: ['dashboard'],
|
||||
},
|
||||
'filters:pinnedByDefault': {
|
||||
name: i18n.translate('kbn.advancedSettings.pinFiltersTitle', {
|
||||
defaultMessage: 'Pin filters by default',
|
||||
|
|
|
@ -26,7 +26,6 @@ import Visualization from './visualization';
|
|||
import VisPicker from './vis_picker';
|
||||
import PanelConfig from './panel_config';
|
||||
import brushHandler from '../lib/create_brush_handler';
|
||||
import { get } from 'lodash';
|
||||
import { extractIndexPatterns } from '../lib/extract_index_patterns';
|
||||
import { fetchFields } from '../lib/fetch_fields';
|
||||
import chrome from 'ui/chrome';
|
||||
|
@ -37,17 +36,14 @@ class VisEditor extends Component {
|
|||
super(props);
|
||||
const { vis } = props;
|
||||
this.appState = vis.API.getAppState();
|
||||
const reversed = get(this.appState, 'options.darkTheme', false);
|
||||
this.state = {
|
||||
model: props.vis.params,
|
||||
dirty: false,
|
||||
autoApply: true,
|
||||
reversed,
|
||||
visFields: {},
|
||||
};
|
||||
this.onBrush = brushHandler(props.vis.API.timeFilter);
|
||||
this.handleUiState = this.handleUiState.bind(this, props.vis);
|
||||
this.handleAppStateChange = this.handleAppStateChange.bind(this);
|
||||
this.getConfig = this.getConfig.bind(this);
|
||||
this.visDataSubject = new Rx.Subject();
|
||||
this.visData$ = this.visDataSubject.asObservable().pipe(share());
|
||||
|
@ -61,23 +57,6 @@ class VisEditor extends Component {
|
|||
vis.uiStateVal(...args);
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
if (this.appState) {
|
||||
this.appState.on('save_with_changes', this.handleAppStateChange);
|
||||
}
|
||||
}
|
||||
|
||||
handleAppStateChange() {
|
||||
const reversed = get(this.appState, 'options.darkTheme', false);
|
||||
this.setState({ reversed });
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.appState) {
|
||||
this.appState.off('save_with_changes', this.handleAppStateChange);
|
||||
}
|
||||
}
|
||||
|
||||
fetchIndexPatternFields = async () => {
|
||||
const { params } = this.props.vis;
|
||||
const { visFields } = this.state;
|
||||
|
@ -134,12 +113,11 @@ class VisEditor extends Component {
|
|||
if (!this.props.vis.params || !this.props.visData) {
|
||||
return null;
|
||||
}
|
||||
const reversed = this.state.reversed;
|
||||
return (
|
||||
<I18nProvider>
|
||||
<Visualization
|
||||
dateFormat={this.props.config.get('dateFormat')}
|
||||
reversed={reversed}
|
||||
reversed={false}
|
||||
onBrush={this.onBrush}
|
||||
onUiState={this.handleUiState}
|
||||
uiState={this.props.vis.getUiState()}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
// depending on dark/light theme and/or background color provided
|
||||
// An easier way would be to provide if the theme is dark in the JS,
|
||||
// but it wasn't passed down.
|
||||
.tab-dashboard.theme-dark .tvbVisMetric--noBackground &,
|
||||
.tvbVisMetric--reversed & {
|
||||
@content;
|
||||
}
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import getRequestParams from './get_request_params';
|
||||
import handleResponseBody from './handle_response_body';
|
||||
import handleErrorResponse from '../handle_error_response';
|
||||
import getLastValue from '../../../../common/get_last_value';
|
||||
import _ from 'lodash';
|
||||
import regression from 'regression';
|
||||
export function getColumnData(req, panel, entities, client) {
|
||||
const elasticsearch = _.get(req, 'server.plugins.elasticsearch');
|
||||
if (elasticsearch) {
|
||||
const { callWithRequest } = elasticsearch.getCluster('data');
|
||||
if (!client) {
|
||||
client = callWithRequest.bind(null, req);
|
||||
}
|
||||
}
|
||||
const params = {
|
||||
rest_total_hits_as_int: true,
|
||||
body: getRequestParams(req, panel, entities)
|
||||
};
|
||||
return client('msearch', params)
|
||||
.then(resp => {
|
||||
const handler = handleResponseBody(panel);
|
||||
return entities.map((entity, index) => {
|
||||
entity.data = {};
|
||||
handler(resp.responses[index]).forEach(row => {
|
||||
const linearRegression = regression('linear', row.data);
|
||||
entity.data[row.id] = {
|
||||
last: getLastValue(row.data),
|
||||
slope: linearRegression.equation[0],
|
||||
yIntercept: linearRegression.equation[1],
|
||||
label: row.label
|
||||
};
|
||||
});
|
||||
return entity;
|
||||
});
|
||||
})
|
||||
.catch(handleErrorResponse(panel));
|
||||
}
|
||||
|
|
@ -34,10 +34,6 @@
|
|||
.ngLegendValue {
|
||||
color: $euiTextColor;
|
||||
|
||||
.tab-dashboard.theme-dark & {
|
||||
color: $euiColorLightShade;
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
|
@ -52,10 +48,6 @@
|
|||
|
||||
.flot-tick-label {
|
||||
color: $euiColorDarkShade;
|
||||
|
||||
.tab-dashboard.theme-dark & {
|
||||
color: $euiColorMediumShade;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,8 +55,4 @@
|
|||
color: $euiTextColor;
|
||||
white-space: nowrap;
|
||||
font-weight: $euiFontWeightBold;
|
||||
|
||||
.tab-dashboard.theme-dark & {
|
||||
color: $euiColorLightShade;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ const STATS_WARNINGS_FILTER = new RegExp([
|
|||
|
||||
export default class BaseOptimizer {
|
||||
constructor(opts) {
|
||||
this.log = opts.log || (() => null);
|
||||
this.logWithMetadata = opts.logWithMetadata || (() => null);
|
||||
this.uiBundles = opts.uiBundles;
|
||||
this.profile = opts.profile || false;
|
||||
|
||||
|
@ -270,7 +270,7 @@ export default class BaseOptimizer {
|
|||
new DynamicDllPlugin({
|
||||
uiBundles: this.uiBundles,
|
||||
threadLoaderPoolConfig: this.getThreadLoaderPoolConfig(),
|
||||
log: this.log
|
||||
logWithMetadata: this.logWithMetadata
|
||||
}),
|
||||
|
||||
new MiniCssExtractPlugin({
|
||||
|
|
|
@ -51,13 +51,13 @@ export class DllCompiler {
|
|||
};
|
||||
}
|
||||
|
||||
constructor(uiBundles, threadLoaderPoolConfig, log) {
|
||||
constructor(uiBundles, threadLoaderPoolConfig, logWithMetadata) {
|
||||
this.rawDllConfig = DllCompiler.getRawDllConfig(
|
||||
uiBundles,
|
||||
uiBundles.getCacheDirectory('babel'),
|
||||
threadLoaderPoolConfig
|
||||
);
|
||||
this.log = log || (() => null);
|
||||
this.logWithMetadata = logWithMetadata || (() => null);
|
||||
}
|
||||
|
||||
async init() {
|
||||
|
@ -182,7 +182,7 @@ export class DllCompiler {
|
|||
|
||||
async runWebpack(config) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.log(['info', 'optimize:dynamic_dll_plugin'], 'Client vendors dll compilation started');
|
||||
this.logWithMetadata(['info', 'optimize:dynamic_dll_plugin'], 'Client vendors dll compilation started');
|
||||
|
||||
webpack(config, (err, stats) => {
|
||||
// If a critical error occurs or we have
|
||||
|
@ -197,7 +197,7 @@ export class DllCompiler {
|
|||
}));
|
||||
|
||||
if (webpackErrors) {
|
||||
this.log(
|
||||
this.logWithMetadata(
|
||||
['fatal', 'optimize:dynamic_dll_plugin'],
|
||||
`Client vendors dll compilation failed`
|
||||
);
|
||||
|
@ -205,7 +205,7 @@ export class DllCompiler {
|
|||
}
|
||||
|
||||
// Otherwise let it proceed
|
||||
this.log(
|
||||
this.logWithMetadata(
|
||||
['info', 'optimize:dynamic_dll_plugin'],
|
||||
`Client vendors dll compilation finished with success`
|
||||
);
|
||||
|
|
|
@ -40,9 +40,9 @@ function inPluginNodeModules(checkPath) {
|
|||
}
|
||||
|
||||
export class DynamicDllPlugin {
|
||||
constructor({ uiBundles, threadLoaderPoolConfig, log, maxCompilations = 1 }) {
|
||||
this.log = log || (() => null);
|
||||
this.dllCompiler = new DllCompiler(uiBundles, threadLoaderPoolConfig, log);
|
||||
constructor({ uiBundles, threadLoaderPoolConfig, logWithMetadata, maxCompilations = 1 }) {
|
||||
this.logWithMetadata = logWithMetadata || (() => null);
|
||||
this.dllCompiler = new DllCompiler(uiBundles, threadLoaderPoolConfig, logWithMetadata);
|
||||
this.entryPaths = '';
|
||||
this.afterCompilationEntryPaths = '';
|
||||
this.maxCompilations = maxCompilations;
|
||||
|
@ -92,7 +92,7 @@ export class DynamicDllPlugin {
|
|||
}
|
||||
|
||||
registerTasksHooks(compiler) {
|
||||
this.log(['info', 'optimize:dynamic_dll_plugin'], 'Started dynamic dll plugin tasks');
|
||||
this.logWithMetadata(['info', 'optimize:dynamic_dll_plugin'], 'Started dynamic dll plugin tasks');
|
||||
this.registerBeforeCompileHook(compiler);
|
||||
this.registerCompilationHook(compiler);
|
||||
this.registerDoneHook(compiler);
|
||||
|
@ -231,7 +231,7 @@ export class DynamicDllPlugin {
|
|||
// Only run this info log in the first performed dll compilation
|
||||
// per each execution run
|
||||
if (this.performedCompilations === 0) {
|
||||
this.log(
|
||||
this.logWithMetadata(
|
||||
['info', 'optimize:dynamic_dll_plugin'],
|
||||
compilation.needsDLLCompilation
|
||||
? 'Need to compile the client vendors dll'
|
||||
|
@ -269,7 +269,7 @@ export class DynamicDllPlugin {
|
|||
if (this.forceDLLCreationFlag) {
|
||||
this.forceDLLCreationFlag = false;
|
||||
}
|
||||
this.log(['info', 'optimize:dynamic_dll_plugin'], 'Finished all dynamic dll plugin tasks');
|
||||
this.logWithMetadata(['info', 'optimize:dynamic_dll_plugin'], 'Finished all dynamic dll plugin tasks');
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ export default async (kbnServer, server, config) => {
|
|||
|
||||
// only require the FsOptimizer when we need to
|
||||
const optimizer = new FsOptimizer({
|
||||
log: (tags, data) => server.log(tags, data),
|
||||
logWithMetadata: (tags, message, metadata) => server.logWithMetadata(tags, message, metadata),
|
||||
uiBundles,
|
||||
profile: config.get('optimize.profile'),
|
||||
sourceMaps: config.get('optimize.sourceMaps'),
|
||||
|
|
|
@ -25,16 +25,16 @@ import { DllCompiler } from '../dynamic_dll_plugin';
|
|||
import { WatchCache } from './watch_cache';
|
||||
|
||||
export default async (kbnServer, kibanaHapiServer, config) => {
|
||||
const log = (tags, data) => kibanaHapiServer.log(tags, data);
|
||||
const logWithMetadata = (tags, message, metadata) => kibanaHapiServer.logWithMetadata(tags, message, metadata);
|
||||
|
||||
const watchOptimizer = new WatchOptimizer({
|
||||
log,
|
||||
logWithMetadata,
|
||||
uiBundles: kbnServer.uiBundles,
|
||||
profile: config.get('optimize.profile'),
|
||||
sourceMaps: config.get('optimize.sourceMaps'),
|
||||
prebuild: config.get('optimize.watchPrebuild'),
|
||||
watchCache: new WatchCache({
|
||||
log,
|
||||
logWithMetadata,
|
||||
outputPath: config.get('path.data'),
|
||||
dllsPath: DllCompiler.getRawDllConfig().outputPath,
|
||||
cachePath: resolve(kbnServer.uiBundles.getCacheDirectory(), '../'),
|
||||
|
|
|
@ -31,7 +31,7 @@ const readAsync = promisify(readFile);
|
|||
const writeAsync = promisify(writeFile);
|
||||
|
||||
interface Params {
|
||||
log: (tags: string[], data: string) => void;
|
||||
logWithMetadata: (tags: string[], message: string, metadata?: { [key: string]: any }) => void;
|
||||
outputPath: string;
|
||||
dllsPath: string;
|
||||
cachePath: string;
|
||||
|
@ -43,7 +43,7 @@ interface WatchCacheStateContent {
|
|||
}
|
||||
|
||||
export class WatchCache {
|
||||
private readonly log: Params['log'];
|
||||
private readonly logWithMetadata: Params['logWithMetadata'];
|
||||
private readonly outputPath: Params['outputPath'];
|
||||
private readonly dllsPath: Params['dllsPath'];
|
||||
private readonly cachePath: Params['cachePath'];
|
||||
|
@ -53,7 +53,7 @@ export class WatchCache {
|
|||
private isInitialized: boolean;
|
||||
|
||||
constructor(params: Params) {
|
||||
this.log = params.log;
|
||||
this.logWithMetadata = params.logWithMetadata;
|
||||
this.outputPath = params.outputPath;
|
||||
this.dllsPath = params.dllsPath;
|
||||
this.cachePath = params.cachePath;
|
||||
|
@ -87,7 +87,7 @@ export class WatchCache {
|
|||
}
|
||||
|
||||
public async reset() {
|
||||
this.log(['info', 'optimize:watch_cache'], 'The optimizer watch cache will reset');
|
||||
this.logWithMetadata(['info', 'optimize:watch_cache'], 'The optimizer watch cache will reset');
|
||||
|
||||
// start by deleting the state file to lower the
|
||||
// amount of time that another process might be able to
|
||||
|
@ -116,7 +116,7 @@ export class WatchCache {
|
|||
// re-write new cache state file
|
||||
await this.write();
|
||||
|
||||
this.log(['info', 'optimize:watch_cache'], 'The optimizer watch cache has reset');
|
||||
this.logWithMetadata(['info', 'optimize:watch_cache'], 'The optimizer watch cache has reset');
|
||||
}
|
||||
|
||||
private async buildShaWithMultipleFiles(filePaths: string[]) {
|
||||
|
|
|
@ -156,16 +156,14 @@ export default class WatchOptimizer extends BaseOptimizer {
|
|||
switch (type) {
|
||||
case STATUS.RUNNING:
|
||||
if (!this.initialBuildComplete) {
|
||||
this.log(['info', 'optimize'], {
|
||||
tmpl: 'Optimization started',
|
||||
this.logWithMetadata(['info', 'optimize'], `Optimization started`, {
|
||||
bundles: this.uiBundles.getIds()
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case STATUS.SUCCESS:
|
||||
this.log(['info', 'optimize'], {
|
||||
tmpl: 'Optimization <%= status %> in <%= seconds %> seconds',
|
||||
this.logWithMetadata(['info', 'optimize'], `Optimization success in ${seconds} seconds`, {
|
||||
bundles: this.uiBundles.getIds(),
|
||||
status: 'success',
|
||||
seconds
|
||||
|
@ -176,8 +174,7 @@ export default class WatchOptimizer extends BaseOptimizer {
|
|||
// errors during initialization to the server, unlike the rest of the
|
||||
// errors produced here. Lets not muddy the console with extra errors
|
||||
if (!this.initializing) {
|
||||
this.log(['fatal', 'optimize'], {
|
||||
tmpl: 'Optimization <%= status %> in <%= seconds %> seconds<%= err %>',
|
||||
this.logWithMetadata(['fatal', 'optimize'], `Optimization failed in ${seconds} seconds${error}`, {
|
||||
bundles: this.uiBundles.getIds(),
|
||||
status: 'failed',
|
||||
seconds,
|
||||
|
@ -187,7 +184,7 @@ export default class WatchOptimizer extends BaseOptimizer {
|
|||
break;
|
||||
|
||||
case STATUS.FATAL:
|
||||
this.log('fatal', error);
|
||||
this.logWithMetadata('fatal', error);
|
||||
process.exit(1);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -124,7 +124,10 @@ export class Config {
|
|||
});
|
||||
|
||||
if (results.error) {
|
||||
throw results.error;
|
||||
const error = new Error(results.error.message);
|
||||
error.name = results.error.name;
|
||||
error.stack = results.error.stack;
|
||||
throw error;
|
||||
}
|
||||
|
||||
this[vals] = results.value;
|
||||
|
|
|
@ -174,7 +174,7 @@ describe('lib/config/config', function () {
|
|||
});
|
||||
|
||||
it('should thow an exception when setting a value with the wrong type', function (done) {
|
||||
expect.assertions(2);
|
||||
expect.assertions(4);
|
||||
|
||||
const run = function () {
|
||||
config.set('test.enable', 'something');
|
||||
|
@ -184,7 +184,11 @@ describe('lib/config/config', function () {
|
|||
run();
|
||||
} catch (err) {
|
||||
expect(err).toHaveProperty('name', 'ValidationError');
|
||||
expect(err.details[0].message).toBe('"enable" must be a boolean');
|
||||
expect(err).toHaveProperty('message',
|
||||
'child \"test\" fails because [child \"enable\" fails because [\"enable\" must be a boolean]]'
|
||||
);
|
||||
expect(err).not.toHaveProperty('details');
|
||||
expect(err).not.toHaveProperty('_object');
|
||||
}
|
||||
|
||||
done();
|
||||
|
|
|
@ -162,11 +162,6 @@ export default class TransformObjStream extends Stream.Transform {
|
|||
else if (logWithMetadata.isLogEvent(event.data)) {
|
||||
_.assign(data, logWithMetadata.getLogEventData(event.data));
|
||||
}
|
||||
else if (_.isPlainObject(event.data) && event.data.tmpl) {
|
||||
_.assign(data, event.data);
|
||||
data.tmpl = undefined;
|
||||
data.message = _.template(event.data.tmpl)(event.data);
|
||||
}
|
||||
else {
|
||||
data.message = _.isString(event.data) ? event.data : inspect(event.data);
|
||||
}
|
||||
|
|
|
@ -33,24 +33,23 @@ export default Promise.method(function (kbnServer, server, config) {
|
|||
.catch(function (err) {
|
||||
if (err.code !== 'EEXIST') throw err;
|
||||
|
||||
const log = {
|
||||
tmpl: 'pid file already exists at <%= path %>',
|
||||
const message = `pid file already exists at ${path}`;
|
||||
const metadata = {
|
||||
path: path,
|
||||
pid: pid
|
||||
};
|
||||
|
||||
if (config.get('pid.exclusive')) {
|
||||
throw Boom.internal(_.template(log.tmpl)(log), log);
|
||||
throw Boom.internal(message, { message, ...metadata });
|
||||
} else {
|
||||
server.log(['pid', 'warning'], log);
|
||||
server.log(['pid', 'warning'], message, metadata);
|
||||
}
|
||||
|
||||
return writeFile(path, pid);
|
||||
})
|
||||
.then(function () {
|
||||
|
||||
server.log(['pid', 'debug'], {
|
||||
tmpl: 'wrote pid file to <%= path %>',
|
||||
server.logWithMetadata(['pid', 'debug'], `wrote pid file to ${path}`, {
|
||||
path: path,
|
||||
pid: pid
|
||||
});
|
||||
|
|
|
@ -66,8 +66,7 @@ export class Plugin {
|
|||
this._server = server;
|
||||
this._options = options;
|
||||
|
||||
server.log(['plugins', 'debug'], {
|
||||
tmpl: 'Initializing plugin <%= plugin.toString() %>',
|
||||
server.logWithMetadata(['plugins', 'debug'], `Initializing plugin ${this.toString()}`, {
|
||||
plugin: this
|
||||
});
|
||||
|
||||
|
|
|
@ -38,17 +38,16 @@ export async function scanMixin(kbnServer, server, config) {
|
|||
const logging$ = Rx.merge(
|
||||
pack$.pipe(
|
||||
tap(definition => {
|
||||
server.log(['plugin', 'debug'], {
|
||||
tmpl: 'Found plugin at <%= path %>',
|
||||
path: definition.getPath()
|
||||
const path = definition.getPath();
|
||||
server.logWithMetadata(['plugin', 'debug'], `Found plugin at ${path}`, {
|
||||
path
|
||||
});
|
||||
})
|
||||
),
|
||||
|
||||
invalidDirectoryError$.pipe(
|
||||
tap(error => {
|
||||
server.log(['plugin', 'warning'], {
|
||||
tmpl: '<%= err.code %>: Unable to scan directory for plugins "<%= dir %>"',
|
||||
server.logWithMetadata(['plugin', 'warning'], `${error.code}: Unable to scan directory for plugins "${error.path}"`, {
|
||||
err: error,
|
||||
dir: error.path
|
||||
});
|
||||
|
@ -57,8 +56,7 @@ export async function scanMixin(kbnServer, server, config) {
|
|||
|
||||
invalidPackError$.pipe(
|
||||
tap(error => {
|
||||
server.log(['plugin', 'warning'], {
|
||||
tmpl: 'Skipping non-plugin directory at <%= path %>',
|
||||
server.logWithMetadata(['plugin', 'warning'], `Skipping non-plugin directory at ${error.path}`, {
|
||||
path: error.path
|
||||
});
|
||||
})
|
||||
|
|
|
@ -28,6 +28,7 @@ export const getSavedObjects = () => [
|
|||
"type": "visualization",
|
||||
"updated_at": "2018-10-01T15:13:03.270Z",
|
||||
"version": 1,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.ecommerceSpec.salesByCategoryTitle', {
|
||||
defaultMessage: '[eCommerce] Sales by Category',
|
||||
|
@ -46,6 +47,7 @@ export const getSavedObjects = () => [
|
|||
"type": "visualization",
|
||||
"updated_at": "2018-10-01T15:13:03.270Z",
|
||||
"version": 1,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.ecommerceSpec.salesByGenderTitle', {
|
||||
defaultMessage: '[eCommerce] Sales by Gender',
|
||||
|
@ -64,6 +66,7 @@ export const getSavedObjects = () => [
|
|||
"type": "visualization",
|
||||
"updated_at": "2018-10-01T15:13:03.270Z",
|
||||
"version": 1,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.ecommerceSpec.markdownTitle', {
|
||||
defaultMessage: '[eCommerce] Markdown',
|
||||
|
@ -82,6 +85,7 @@ export const getSavedObjects = () => [
|
|||
"type": "visualization",
|
||||
"updated_at": "2018-10-01T15:13:03.270Z",
|
||||
"version": 1,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.ecommerceSpec.controlsTitle', {
|
||||
defaultMessage: '[eCommerce] Controls',
|
||||
|
@ -100,6 +104,7 @@ export const getSavedObjects = () => [
|
|||
"type": "visualization",
|
||||
"updated_at": "2018-10-01T15:17:30.755Z",
|
||||
"version": 2,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.ecommerceSpec.promotionTrackingTitle', {
|
||||
defaultMessage: '[eCommerce] Promotion Tracking',
|
||||
|
@ -118,6 +123,7 @@ export const getSavedObjects = () => [
|
|||
"type": "visualization",
|
||||
"updated_at": "2018-10-01T15:13:03.270Z",
|
||||
"version": 1,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.ecommerceSpec.totalRevenueTitle', {
|
||||
defaultMessage: '[eCommerce] Total Revenue',
|
||||
|
@ -136,6 +142,7 @@ export const getSavedObjects = () => [
|
|||
"type": "visualization",
|
||||
"updated_at": "2018-10-01T15:13:03.270Z",
|
||||
"version": 1,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.ecommerceSpec.soldProductsPerDayTitle', {
|
||||
defaultMessage: '[eCommerce] Sold Products per Day',
|
||||
|
@ -154,6 +161,7 @@ export const getSavedObjects = () => [
|
|||
"type": "visualization",
|
||||
"updated_at": "2018-10-01T15:13:03.270Z",
|
||||
"version": 1,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.ecommerceSpec.averageSalesPriceTitle', {
|
||||
defaultMessage: '[eCommerce] Average Sales Price',
|
||||
|
@ -172,6 +180,7 @@ export const getSavedObjects = () => [
|
|||
"type": "visualization",
|
||||
"updated_at": "2018-10-01T15:13:03.270Z",
|
||||
"version": 1,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.ecommerceSpec.averageSoldQuantityTitle', {
|
||||
defaultMessage: '[eCommerce] Average Sold Quantity',
|
||||
|
@ -190,6 +199,7 @@ export const getSavedObjects = () => [
|
|||
"type": "search",
|
||||
"updated_at": "2018-10-01T15:13:03.270Z",
|
||||
"version": 1,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.ecommerceSpec.ordersTitle', {
|
||||
defaultMessage: '[eCommerce] Orders',
|
||||
|
@ -217,6 +227,7 @@ export const getSavedObjects = () => [
|
|||
"type": "visualization",
|
||||
"updated_at": "2018-10-01T15:13:03.270Z",
|
||||
"version": 1,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.ecommerceSpec.averageSalesPerRegionTitle', {
|
||||
defaultMessage: '[eCommerce] Average Sales Per Region',
|
||||
|
@ -235,6 +246,7 @@ export const getSavedObjects = () => [
|
|||
"type": "visualization",
|
||||
"updated_at": "2018-10-01T15:13:03.270Z",
|
||||
"version": 1,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.ecommerceSpec.topSellingProductsTitle', {
|
||||
defaultMessage: '[eCommerce] Top Selling Products',
|
||||
|
@ -253,6 +265,7 @@ export const getSavedObjects = () => [
|
|||
"type": "index-pattern",
|
||||
"updated_at": "2018-10-01T15:13:03.270Z",
|
||||
"version": 1,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": "kibana_sample_data_ecommerce",
|
||||
"timeFieldName": "order_date",
|
||||
|
@ -265,6 +278,7 @@ export const getSavedObjects = () => [
|
|||
"type": "dashboard",
|
||||
"updated_at": "2018-10-01T15:13:03.270Z",
|
||||
"version": 1,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.ecommerceSpec.revenueDashboardTitle', {
|
||||
defaultMessage: '[eCommerce] Revenue Dashboard',
|
||||
|
@ -274,7 +288,7 @@ export const getSavedObjects = () => [
|
|||
defaultMessage: 'Analyze mock eCommerce orders and revenue',
|
||||
}),
|
||||
"panelsJSON": "[{\"embeddableConfig\":{\"vis\":{\"colors\":{\"Men's Accessories\":\"#82B5D8\",\"Men's Clothing\":\"#F9BA8F\",\"Men's Shoes\":\"#F29191\",\"Women's Accessories\":\"#F4D598\",\"Women's Clothing\":\"#70DBED\",\"Women's Shoes\":\"#B7DBAB\"}}},\"gridData\":{\"x\":12,\"y\":18,\"w\":36,\"h\":10,\"i\":\"1\"},\"id\":\"37cc8650-b882-11e8-a6d9-e546fe2bba5f\",\"panelIndex\":\"1\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{\"vis\":{\"colors\":{\"FEMALE\":\"#6ED0E0\",\"MALE\":\"#447EBC\"},\"legendOpen\":false}},\"gridData\":{\"x\":12,\"y\":7,\"w\":12,\"h\":11,\"i\":\"2\"},\"id\":\"ed8436b0-b88b-11e8-a6d9-e546fe2bba5f\",\"panelIndex\":\"2\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{},\"gridData\":{\"x\":0,\"y\":0,\"w\":18,\"h\":7,\"i\":\"3\"},\"id\":\"09ffee60-b88c-11e8-a6d9-e546fe2bba5f\",\"panelIndex\":\"3\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{},\"gridData\":{\"x\":18,\"y\":0,\"w\":30,\"h\":7,\"i\":\"4\"},\"id\":\"1c389590-b88d-11e8-a6d9-e546fe2bba5f\",\"panelIndex\":\"4\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{},\"gridData\":{\"x\":0,\"y\":28,\"w\":48,\"h\":11,\"i\":\"5\"},\"id\":\"45e07720-b890-11e8-a6d9-e546fe2bba5f\",\"panelIndex\":\"5\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{},\"gridData\":{\"x\":0,\"y\":18,\"w\":12,\"h\":10,\"i\":\"6\"},\"id\":\"10f1a240-b891-11e8-a6d9-e546fe2bba5f\",\"panelIndex\":\"6\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{},\"gridData\":{\"x\":0,\"y\":7,\"w\":12,\"h\":11,\"i\":\"7\"},\"id\":\"b80e6540-b891-11e8-a6d9-e546fe2bba5f\",\"panelIndex\":\"7\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{\"vis\":{\"colors\":{\"0 - 50\":\"#E24D42\",\"50 - 75\":\"#EAB839\",\"75 - 100\":\"#7EB26D\"},\"defaultColors\":{\"0 - 50\":\"rgb(165,0,38)\",\"50 - 75\":\"rgb(255,255,190)\",\"75 - 100\":\"rgb(0,104,55)\"},\"legendOpen\":false}},\"gridData\":{\"x\":24,\"y\":7,\"w\":12,\"h\":11,\"i\":\"8\"},\"id\":\"4b3ec120-b892-11e8-a6d9-e546fe2bba5f\",\"panelIndex\":\"8\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{\"vis\":{\"colors\":{\"0 - 2\":\"#E24D42\",\"2 - 3\":\"#F2C96D\",\"3 - 4\":\"#9AC48A\"},\"defaultColors\":{\"0 - 2\":\"rgb(165,0,38)\",\"2 - 3\":\"rgb(255,255,190)\",\"3 - 4\":\"rgb(0,104,55)\"},\"legendOpen\":false}},\"gridData\":{\"x\":36,\"y\":7,\"w\":12,\"h\":11,\"i\":\"9\"},\"id\":\"9ca7aa90-b892-11e8-a6d9-e546fe2bba5f\",\"panelIndex\":\"9\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{},\"gridData\":{\"x\":0,\"y\":54,\"w\":48,\"h\":18,\"i\":\"10\"},\"id\":\"3ba638e0-b894-11e8-a6d9-e546fe2bba5f\",\"panelIndex\":\"10\",\"type\":\"search\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{\"mapZoom\":2,\"mapCenter\":[28.304380682962783,-22.148437500000004]},\"gridData\":{\"x\":0,\"y\":39,\"w\":24,\"h\":15,\"i\":\"11\"},\"id\":\"9c6f83f0-bb4d-11e8-9c84-77068524bcab\",\"panelIndex\":\"11\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{},\"gridData\":{\"x\":24,\"y\":39,\"w\":24,\"h\":15,\"i\":\"12\"},\"id\":\"b72dd430-bb4d-11e8-9c84-77068524bcab\",\"panelIndex\":\"12\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"}]",
|
||||
"optionsJSON": "{\"darkTheme\":false,\"hidePanelTitles\":false,\"useMargins\":true}",
|
||||
"optionsJSON": "{\"hidePanelTitles\":false,\"useMargins\":true}",
|
||||
"version": 1,
|
||||
"timeRestore": true,
|
||||
"timeTo": "now",
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -28,6 +28,7 @@ export const getSavedObjects = () => [
|
|||
"type": "visualization",
|
||||
"updated_at": "2018-08-29T13:22:17.617Z",
|
||||
"version": 1,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.logsSpec.uniqueVisitorsTitle', {
|
||||
defaultMessage: '[Logs] Unique Visitors vs. Average Bytes',
|
||||
|
@ -46,6 +47,7 @@ export const getSavedObjects = () => [
|
|||
"type": "visualization",
|
||||
"updated_at": "2018-08-29T13:22:17.617Z",
|
||||
"version": 1,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.logsSpec.uniqueVisitorsByCountryTitle', {
|
||||
defaultMessage: '[Logs] Unique Visitors by Country',
|
||||
|
@ -64,6 +66,7 @@ export const getSavedObjects = () => [
|
|||
"type": "visualization",
|
||||
"updated_at": "2018-08-29T13:22:17.617Z",
|
||||
"version": 1,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.logsSpec.heatmapTitle', {
|
||||
defaultMessage: '[Logs] Heatmap',
|
||||
|
@ -82,6 +85,7 @@ export const getSavedObjects = () => [
|
|||
"type": "visualization",
|
||||
"updated_at": "2018-08-29T13:23:20.897Z",
|
||||
"version": 2,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.logsSpec.hostVisitsBytesTableTitle', {
|
||||
defaultMessage: '[Logs] Host, Visits and Bytes Table',
|
||||
|
@ -100,6 +104,7 @@ export const getSavedObjects = () => [
|
|||
"type": "visualization",
|
||||
"updated_at": "2018-08-29T13:24:46.136Z",
|
||||
"version": 2,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.logsSpec.goalsTitle', {
|
||||
defaultMessage: '[Logs] Goals',
|
||||
|
@ -118,6 +123,7 @@ export const getSavedObjects = () => [
|
|||
"type": "visualization",
|
||||
"updated_at": "2018-08-29T13:22:17.617Z",
|
||||
"version": 1,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.logsSpec.fileTypeScatterPlotTitle', {
|
||||
defaultMessage: '[Logs] File Type Scatter Plot',
|
||||
|
@ -136,6 +142,7 @@ export const getSavedObjects = () => [
|
|||
"type": "visualization",
|
||||
"updated_at": "2018-08-29T13:22:17.617Z",
|
||||
"version": 1,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.logsSpec.sourceAndDestinationSankeyChartTitle', {
|
||||
defaultMessage: '[Logs] Source and Destination Sankey Chart',
|
||||
|
@ -154,6 +161,7 @@ export const getSavedObjects = () => [
|
|||
"type": "visualization",
|
||||
"updated_at": "2018-08-29T13:22:17.617Z",
|
||||
"version": 1,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.logsSpec.responseCodesOverTimeTitle', {
|
||||
defaultMessage: '[Logs] Response Codes Over Time + Annotations',
|
||||
|
@ -172,6 +180,7 @@ export const getSavedObjects = () => [
|
|||
"type": "visualization",
|
||||
"updated_at": "2018-08-29T13:22:17.617Z",
|
||||
"version": 1,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.logsSpec.inputControlsTitle', {
|
||||
defaultMessage: '[Logs] Input Controls',
|
||||
|
@ -190,6 +199,7 @@ export const getSavedObjects = () => [
|
|||
"type": "visualization",
|
||||
"updated_at": "2018-08-29T13:22:17.617Z",
|
||||
"version": 1,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.logsSpec.articleTagsTitle', {
|
||||
defaultMessage: '[Logs] Article Tags',
|
||||
|
@ -208,6 +218,7 @@ export const getSavedObjects = () => [
|
|||
"type": "visualization",
|
||||
"updated_at": "2018-08-29T13:22:17.617Z",
|
||||
"version": 1,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.logsSpec.markdownInstructionsTitle', {
|
||||
defaultMessage: '[Logs] Markdown Instructions',
|
||||
|
@ -226,6 +237,7 @@ export const getSavedObjects = () => [
|
|||
"type": "index-pattern",
|
||||
"updated_at": "2018-08-29T13:22:17.617Z",
|
||||
"version": 1,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": "kibana_sample_data_logs",
|
||||
"timeFieldName": "timestamp",
|
||||
|
@ -238,6 +250,7 @@ export const getSavedObjects = () => [
|
|||
"type": "dashboard",
|
||||
"updated_at": "2018-08-29T13:26:13.463Z",
|
||||
"version": 3,
|
||||
"migrationVersion": {},
|
||||
"attributes": {
|
||||
"title": i18n.translate('server.sampleData.logsSpec.webTrafficTitle', {
|
||||
defaultMessage: '[Logs] Web Traffic',
|
||||
|
@ -247,7 +260,7 @@ export const getSavedObjects = () => [
|
|||
defaultMessage: 'Analyze mock web traffic log data for Elastic\'s website',
|
||||
}),
|
||||
"panelsJSON": "[{\"embeddableConfig\":{\"vis\":{\"colors\":{\"Avg. Bytes\":\"#6ED0E0\",\"Unique Visitors\":\"#0A437C\"},\"legendOpen\":false}},\"gridData\":{\"x\":27,\"y\":11,\"w\":21,\"h\":13,\"i\":\"2\"},\"id\":\"e1d0f010-9ee7-11e7-8711-e7a007dcef99\",\"panelIndex\":\"2\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"gridData\":{\"x\":0,\"y\":49,\"w\":24,\"h\":18,\"i\":\"4\"},\"id\":\"06cf9c40-9ee8-11e7-8711-e7a007dcef99\",\"panelIndex\":\"4\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"},{\"embeddableConfig\":{\"vis\":{\"defaultColors\":{\"0 - 22\":\"rgb(247,251,255)\",\"22 - 44\":\"rgb(208,225,242)\",\"44 - 66\":\"rgb(148,196,223)\",\"66 - 88\":\"rgb(74,152,201)\",\"88 - 110\":\"rgb(23,100,171)\"},\"legendOpen\":false}},\"gridData\":{\"x\":0,\"y\":36,\"w\":24,\"h\":13,\"i\":\"7\"},\"id\":\"935afa20-e0cd-11e7-9d07-1398ccfcefa3\",\"panelIndex\":\"7\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"embeddableConfig\":{\"mapCenter\":[36.8092847020594,-96.94335937500001],\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"gridData\":{\"x\":27,\"y\":24,\"w\":21,\"h\":12,\"i\":\"9\"},\"id\":\"4eb6e500-e1c7-11e7-b6d5-4dc382ef7f5b\",\"panelIndex\":\"9\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"embeddableConfig\":{\"vis\":{\"colors\":{\"0 - 500\":\"#BF1B00\",\"1000 - 1500\":\"#7EB26D\",\"500 - 1000\":\"#F2C96D\"},\"defaultColors\":{\"0 - 500\":\"rgb(165,0,38)\",\"1000 - 1500\":\"rgb(0,104,55)\",\"500 - 1000\":\"rgb(255,255,190)\"},\"legendOpen\":false}},\"gridData\":{\"x\":10,\"y\":0,\"w\":9,\"h\":11,\"i\":\"11\"},\"id\":\"69a34b00-9ee8-11e7-8711-e7a007dcef99\",\"panelIndex\":\"11\",\"title\":\"\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"gridData\":{\"x\":0,\"y\":24,\"w\":27,\"h\":12,\"i\":\"13\"},\"id\":\"42b997f0-0c26-11e8-b0ec-3bb475f6b6ff\",\"panelIndex\":\"13\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"gridData\":{\"x\":24,\"y\":36,\"w\":24,\"h\":31,\"i\":\"14\"},\"id\":\"7cbd2350-2223-11e8-b802-5bcf64c2cfb4\",\"panelIndex\":\"14\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"gridData\":{\"x\":0,\"y\":11,\"w\":27,\"h\":13,\"i\":\"15\"},\"id\":\"314c6f60-2224-11e8-b802-5bcf64c2cfb4\",\"panelIndex\":\"15\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"gridData\":{\"x\":19,\"y\":0,\"w\":15,\"h\":11,\"i\":\"16\"},\"id\":\"24a3e970-4257-11e8-b3aa-73fdaf54bfc9\",\"panelIndex\":\"16\",\"title\":\"\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"embeddableConfig\":{\"vis\":{\"legendOpen\":false}},\"gridData\":{\"x\":34,\"y\":0,\"w\":14,\"h\":11,\"i\":\"17\"},\"id\":\"14e2e710-4258-11e8-b3aa-73fdaf54bfc9\",\"panelIndex\":\"17\",\"type\":\"visualization\",\"version\":\"6.3.0\"},{\"embeddableConfig\":{},\"gridData\":{\"x\":0,\"y\":0,\"w\":10,\"h\":11,\"i\":\"18\"},\"id\":\"47f2c680-a6e3-11e8-94b4-c30c0228351b\",\"panelIndex\":\"18\",\"title\":\"\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1\"}]",
|
||||
"optionsJSON": "{\"darkTheme\":false,\"hidePanelTitles\":false,\"useMargins\":true}",
|
||||
"optionsJSON": "{\"hidePanelTitles\":false,\"useMargins\":true}",
|
||||
"version": 1,
|
||||
"timeRestore": true,
|
||||
"timeTo": "now",
|
||||
|
|
|
@ -49,17 +49,20 @@ export function createSavedObjectsService(server, schema, serializer, migrator)
|
|||
},
|
||||
});
|
||||
} catch (error) {
|
||||
server.log(['debug', 'savedObjects'], {
|
||||
tmpl: 'Attempt to write indexTemplate for SavedObjects index failed: <%= err.message %>',
|
||||
es: {
|
||||
resp: error.body,
|
||||
status: error.status,
|
||||
},
|
||||
err: {
|
||||
message: error.message,
|
||||
stack: error.stack,
|
||||
},
|
||||
});
|
||||
server.logWithMetadata(
|
||||
['debug', 'savedObjects'],
|
||||
`Attempt to write indexTemplate for SavedObjects index failed: ${error.message}`,
|
||||
{
|
||||
es: {
|
||||
resp: error.body,
|
||||
status: error.status,
|
||||
},
|
||||
err: {
|
||||
message: error.message,
|
||||
stack: error.stack,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
// We reject with `es.ServiceUnavailable` because writing an index
|
||||
// template is a very simple operation so if we get an error here
|
||||
|
|
|
@ -31,7 +31,7 @@ describe('ServerStatus class', function () {
|
|||
let serverStatus;
|
||||
|
||||
beforeEach(function () {
|
||||
server = { expose: sinon.stub(), log: sinon.stub() };
|
||||
server = { expose: sinon.stub(), logWithMetadata: sinon.stub() };
|
||||
serverStatus = new ServerStatus(server);
|
||||
});
|
||||
|
||||
|
|
|
@ -42,13 +42,15 @@ export default class Status extends EventEmitter {
|
|||
this.state === 'red' ? 'error' : 'info'
|
||||
];
|
||||
|
||||
server.log(tags, {
|
||||
tmpl: 'Status changed from <%= prevState %> to <%= state %><%= message ? " - " + message : "" %>',
|
||||
state: this.state,
|
||||
message: this.message,
|
||||
prevState: previous,
|
||||
prevMsg: previousMsg
|
||||
});
|
||||
server.logWithMetadata(tags,
|
||||
`Status changed from ${ previous } to ${this.state}${ this.message ? ' - ' + this.message : '' }`,
|
||||
{
|
||||
state: this.state,
|
||||
message: this.message,
|
||||
prevState: previous,
|
||||
prevMsg: previousMsg
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ describe('Status class', function () {
|
|||
let serverStatus;
|
||||
|
||||
beforeEach(function () {
|
||||
server = { expose: sinon.stub(), log: sinon.stub() };
|
||||
server = { expose: sinon.stub(), logWithMetadata: sinon.stub() };
|
||||
serverStatus = new ServerStatus(server);
|
||||
});
|
||||
|
||||
|
|
|
@ -36,14 +36,3 @@ kbn-agg-table-group {
|
|||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.theme-dark {
|
||||
@import '@elastic/eui/src/themes/k6/k6_colors_dark';
|
||||
|
||||
.kbnAggTable__paginated {
|
||||
tr:hover td,
|
||||
.kbnTableCellFilter {
|
||||
background-color: $euiColorLightestShade;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,11 @@ module.directive('paginatedSelectableList', function () {
|
|||
disableAutoFocus: '='
|
||||
},
|
||||
template: paginatedSelectableListTemplate,
|
||||
controller: function ($scope) {
|
||||
controller: function ($scope, $filter) {
|
||||
function calculateHitsByQuery() {
|
||||
$scope.hitsByQuery = $filter('filter')($scope.hits, $scope.query);
|
||||
}
|
||||
|
||||
// Should specify either user-make-url or user-on-select
|
||||
if (!$scope.userMakeUrl && !$scope.userOnSelect) {
|
||||
throwError('paginatedSelectableList directive expects a makeUrl or onSelect function');
|
||||
|
@ -53,6 +57,8 @@ module.directive('paginatedSelectableList', function () {
|
|||
|
||||
$scope.perPage = $scope.perPage || 10;
|
||||
$scope.hits = $scope.list = _.sortBy($scope.list, $scope.accessor);
|
||||
$scope.$watchGroup(['hits', 'query'], calculateHitsByQuery);
|
||||
calculateHitsByQuery();
|
||||
$scope.hitCount = $scope.hits.length;
|
||||
|
||||
/**
|
||||
|
|
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