mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
Cleanup of the kibanaLegacy unused functions and remove unecessary dependencies from Analytics plugins (#113358)
* [Discover][Table] Remove unused dependencies of the kibanaLegacy plugin * More removals of kibanaLegacy plugin dependencies * Revert discover changes * Remove the unused functions from the kibana_legacy plugin * Removes unused translations
This commit is contained in:
parent
24bbf2cdfc
commit
a9d80ac46a
37 changed files with 2 additions and 1660 deletions
|
@ -10,7 +10,6 @@
|
|||
"data",
|
||||
"embeddable",
|
||||
"inspector",
|
||||
"kibanaLegacy",
|
||||
"navigation",
|
||||
"savedObjects",
|
||||
"share",
|
||||
|
|
|
@ -31,7 +31,6 @@ import { createKbnUrlTracker } from './services/kibana_utils';
|
|||
import { UsageCollectionSetup } from './services/usage_collection';
|
||||
import { UiActionsSetup, UiActionsStart } from './services/ui_actions';
|
||||
import { PresentationUtilPluginStart } from './services/presentation_util';
|
||||
import { KibanaLegacySetup, KibanaLegacyStart } from './services/kibana_legacy';
|
||||
import { FeatureCatalogueCategory, HomePublicPluginSetup } from './services/home';
|
||||
import { NavigationPublicPluginStart as NavigationStart } from './services/navigation';
|
||||
import { DataPublicPluginSetup, DataPublicPluginStart, esFilters } from './services/data';
|
||||
|
@ -98,7 +97,6 @@ export interface DashboardSetupDependencies {
|
|||
data: DataPublicPluginSetup;
|
||||
embeddable: EmbeddableSetup;
|
||||
home?: HomePublicPluginSetup;
|
||||
kibanaLegacy: KibanaLegacySetup;
|
||||
urlForwarding: UrlForwardingSetup;
|
||||
share?: SharePluginSetup;
|
||||
uiActions: UiActionsSetup;
|
||||
|
@ -107,7 +105,6 @@ export interface DashboardSetupDependencies {
|
|||
|
||||
export interface DashboardStartDependencies {
|
||||
data: DataPublicPluginStart;
|
||||
kibanaLegacy: KibanaLegacyStart;
|
||||
urlForwarding: UrlForwardingStart;
|
||||
embeddable: EmbeddableStart;
|
||||
inspector: InspectorStartContract;
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export { KibanaLegacySetup, KibanaLegacyStart } from '../../../kibana_legacy/public';
|
|
@ -16,7 +16,6 @@
|
|||
"references": [
|
||||
{ "path": "../../core/tsconfig.json" },
|
||||
{ "path": "../inspector/tsconfig.json" },
|
||||
{ "path": "../kibana_legacy/tsconfig.json" },
|
||||
{ "path": "../kibana_react/tsconfig.json" },
|
||||
{ "path": "../kibana_utils/tsconfig.json" },
|
||||
{ "path": "../share/tsconfig.json" },
|
||||
|
|
|
@ -5,10 +5,6 @@
|
|||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
// @ts-ignore
|
||||
export { watchMultiDecorator } from './watch_multi';
|
||||
export * from './angular_config';
|
||||
// @ts-ignore
|
||||
export { createTopNavDirective, createTopNavHelper, loadKbnTopNavDirectives } from './kbn_top_nav';
|
||||
export { subscribeWithScope } from './subscribe_with_scope';
|
||||
|
|
|
@ -1,186 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import * as Rx from 'rxjs';
|
||||
import { subscribeWithScope } from './subscribe_with_scope';
|
||||
|
||||
// eslint-disable-next-line prefer-const
|
||||
let $rootScope: Scope;
|
||||
|
||||
class Scope {
|
||||
public $$phase?: string;
|
||||
public $root = $rootScope;
|
||||
public $apply = jest.fn((fn: () => void) => fn());
|
||||
}
|
||||
|
||||
$rootScope = new Scope();
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('subscribes to the passed observable, returns subscription', () => {
|
||||
const $scope = new Scope();
|
||||
|
||||
const unsubSpy = jest.fn();
|
||||
const subSpy = jest.fn<any, any>(() => unsubSpy);
|
||||
const observable = new Rx.Observable(subSpy);
|
||||
|
||||
const subscription = subscribeWithScope($scope as any, observable);
|
||||
expect(subSpy).toHaveBeenCalledTimes(1);
|
||||
expect(unsubSpy).not.toHaveBeenCalled();
|
||||
|
||||
subscription.unsubscribe();
|
||||
|
||||
expect(subSpy).toHaveBeenCalledTimes(1);
|
||||
expect(unsubSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('calls observer.next() if already in a digest cycle, wraps in $scope.$apply if not', () => {
|
||||
const subject = new Rx.Subject();
|
||||
const nextSpy = jest.fn();
|
||||
const $scope = new Scope();
|
||||
|
||||
subscribeWithScope($scope as any, subject, { next: nextSpy });
|
||||
|
||||
subject.next();
|
||||
expect($scope.$apply).toHaveBeenCalledTimes(1);
|
||||
expect(nextSpy).toHaveBeenCalledTimes(1);
|
||||
|
||||
jest.clearAllMocks();
|
||||
|
||||
$rootScope.$$phase = '$digest';
|
||||
subject.next();
|
||||
expect($scope.$apply).not.toHaveBeenCalled();
|
||||
expect(nextSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('reports fatalError if observer.next() throws', () => {
|
||||
const fatalError = jest.fn();
|
||||
const $scope = new Scope();
|
||||
subscribeWithScope(
|
||||
$scope as any,
|
||||
Rx.of(undefined),
|
||||
{
|
||||
next() {
|
||||
throw new Error('foo bar');
|
||||
},
|
||||
},
|
||||
fatalError
|
||||
);
|
||||
|
||||
expect(fatalError.mock.calls).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: foo bar],
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('reports fatal error if observer.error is not defined and observable errors', () => {
|
||||
const fatalError = jest.fn();
|
||||
const $scope = new Scope();
|
||||
const error = new Error('foo');
|
||||
error.stack = `${error.message}\n---stack trace ---`;
|
||||
subscribeWithScope($scope as any, Rx.throwError(error), undefined, fatalError);
|
||||
|
||||
expect(fatalError.mock.calls).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: Uncaught error in subscribeWithScope(): foo
|
||||
---stack trace ---],
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('reports fatal error if observer.error throws', () => {
|
||||
const fatalError = jest.fn();
|
||||
const $scope = new Scope();
|
||||
subscribeWithScope(
|
||||
$scope as any,
|
||||
Rx.throwError(new Error('foo')),
|
||||
{
|
||||
error: () => {
|
||||
throw new Error('foo');
|
||||
},
|
||||
},
|
||||
fatalError
|
||||
);
|
||||
|
||||
expect(fatalError.mock.calls).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: foo],
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('does not report fatal error if observer.error handles the error', () => {
|
||||
const fatalError = jest.fn();
|
||||
const $scope = new Scope();
|
||||
subscribeWithScope(
|
||||
$scope as any,
|
||||
Rx.throwError(new Error('foo')),
|
||||
{
|
||||
error: () => {
|
||||
// noop, swallow error
|
||||
},
|
||||
},
|
||||
fatalError
|
||||
);
|
||||
|
||||
expect(fatalError.mock.calls).toEqual([]);
|
||||
});
|
||||
|
||||
it('reports fatal error if observer.complete throws', () => {
|
||||
const fatalError = jest.fn();
|
||||
const $scope = new Scope();
|
||||
subscribeWithScope(
|
||||
$scope as any,
|
||||
Rx.EMPTY,
|
||||
{
|
||||
complete: () => {
|
||||
throw new Error('foo');
|
||||
},
|
||||
},
|
||||
fatalError
|
||||
);
|
||||
|
||||
expect(fatalError.mock.calls).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: foo],
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('preserves the context of the observer functions', () => {
|
||||
const $scope = new Scope();
|
||||
const observer = {
|
||||
next() {
|
||||
expect(this).toBe(observer);
|
||||
},
|
||||
complete() {
|
||||
expect(this).toBe(observer);
|
||||
},
|
||||
};
|
||||
|
||||
subscribeWithScope($scope as any, Rx.of([1, 2, 3]), observer);
|
||||
|
||||
const observer2 = {
|
||||
error() {
|
||||
expect(this).toBe(observer);
|
||||
},
|
||||
};
|
||||
|
||||
subscribeWithScope($scope as any, Rx.throwError(new Error('foo')), observer2);
|
||||
});
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { IScope } from 'angular';
|
||||
import * as Rx from 'rxjs';
|
||||
import { AngularHttpError } from '../notify/lib';
|
||||
|
||||
type FatalErrorFn = (error: AngularHttpError | Error | string, location?: string) => void;
|
||||
|
||||
function callInDigest($scope: IScope, fn: () => void, fatalError?: FatalErrorFn) {
|
||||
try {
|
||||
// this is terrible, but necessary to synchronously deliver subscription values
|
||||
// to angular scopes. This is required by some APIs, like the `config` service,
|
||||
// and beneficial for root level directives where additional digest cycles make
|
||||
// kibana sluggish to load.
|
||||
//
|
||||
// If you copy this code elsewhere you better have a good reason :)
|
||||
if ($scope.$root.$$phase) {
|
||||
fn();
|
||||
} else {
|
||||
$scope.$apply(() => fn());
|
||||
}
|
||||
} catch (error) {
|
||||
if (fatalError) {
|
||||
fatalError(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to an observable at a $scope, ensuring that the digest cycle
|
||||
* is run for subscriber hooks and routing errors to fatalError if not handled.
|
||||
*/
|
||||
export function subscribeWithScope<T>(
|
||||
$scope: IScope,
|
||||
observable: Rx.Observable<T>,
|
||||
observer?: Rx.PartialObserver<T>,
|
||||
fatalError?: FatalErrorFn
|
||||
) {
|
||||
return observable.subscribe({
|
||||
next(value) {
|
||||
if (observer && observer.next) {
|
||||
callInDigest($scope, () => observer.next!(value), fatalError);
|
||||
}
|
||||
},
|
||||
error(error) {
|
||||
callInDigest(
|
||||
$scope,
|
||||
() => {
|
||||
if (observer && observer.error) {
|
||||
observer.error(error);
|
||||
} else {
|
||||
throw new Error(
|
||||
`Uncaught error in subscribeWithScope(): ${
|
||||
error ? error.stack || error.message : error
|
||||
}`
|
||||
);
|
||||
}
|
||||
},
|
||||
fatalError
|
||||
);
|
||||
},
|
||||
complete() {
|
||||
if (observer && observer.complete) {
|
||||
callInDigest($scope, () => observer.complete!(), fatalError);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export function watchMultiDecorator($provide: unknown): void;
|
|
@ -1,137 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import _ from 'lodash';
|
||||
|
||||
export function watchMultiDecorator($provide) {
|
||||
$provide.decorator('$rootScope', function ($delegate) {
|
||||
/**
|
||||
* Watch multiple expressions with a single callback. Along
|
||||
* with making code simpler it also merges all of the watcher
|
||||
* handlers within a single tick.
|
||||
*
|
||||
* # expression format
|
||||
* expressions can be specified in one of the following ways:
|
||||
* 1. string that evaluates to a value on scope. Creates a regular $watch
|
||||
* expression.
|
||||
* 'someScopeValue.prop' === $scope.$watch('someScopeValue.prop', fn);
|
||||
*
|
||||
* 2. #1 prefixed with '[]', which uses $watchCollection rather than $watch.
|
||||
* '[]expr' === $scope.$watchCollection('expr', fn);
|
||||
*
|
||||
* 3. #1 prefixed with '=', which uses $watch with objectEquality turned on
|
||||
* '=expr' === $scope.$watch('expr', fn, true);
|
||||
*
|
||||
* 4. a function that will be called, like a normal function water
|
||||
*
|
||||
* 5. an object with any of the properties:
|
||||
* `get`: the getter called on each iteration
|
||||
* `deep`: a flag to turn on objectEquality in $watch
|
||||
* `fn`: the watch registration function ($scope.$watch or $scope.$watchCollection)
|
||||
*
|
||||
* @param {array[string|function|obj]} expressions - the list of expressions to $watch
|
||||
* @param {Function} fn - the callback function
|
||||
* @return {Function} - an unwatch function, just like the return value of $watch
|
||||
*/
|
||||
$delegate.constructor.prototype.$watchMulti = function (expressions, fn) {
|
||||
if (!Array.isArray(expressions)) {
|
||||
throw new TypeError('expected an array of expressions to watch');
|
||||
}
|
||||
|
||||
if (!_.isFunction(fn)) {
|
||||
throw new TypeError('expected a function that is triggered on each watch');
|
||||
}
|
||||
const $scope = this;
|
||||
const vals = new Array(expressions.length);
|
||||
const prev = new Array(expressions.length);
|
||||
let fire = false;
|
||||
let init = 0;
|
||||
const neededInits = expressions.length;
|
||||
|
||||
// first, register all of the multi-watchers
|
||||
const unwatchers = expressions.map(function (expr, i) {
|
||||
expr = normalizeExpression($scope, expr);
|
||||
if (!expr) return;
|
||||
|
||||
return expr.fn.call(
|
||||
$scope,
|
||||
expr.get,
|
||||
function (newVal, oldVal) {
|
||||
if (newVal === oldVal) {
|
||||
init += 1;
|
||||
}
|
||||
|
||||
vals[i] = newVal;
|
||||
prev[i] = oldVal;
|
||||
fire = true;
|
||||
},
|
||||
expr.deep
|
||||
);
|
||||
});
|
||||
|
||||
// then, the watcher that checks to see if any of
|
||||
// the other watchers triggered this cycle
|
||||
let flip = false;
|
||||
unwatchers.push(
|
||||
$scope.$watch(
|
||||
function () {
|
||||
if (init < neededInits) return init;
|
||||
|
||||
if (fire) {
|
||||
fire = false;
|
||||
flip = !flip;
|
||||
}
|
||||
return flip;
|
||||
},
|
||||
function () {
|
||||
if (init < neededInits) return false;
|
||||
|
||||
fn(vals.slice(0), prev.slice(0));
|
||||
vals.forEach(function (v, i) {
|
||||
prev[i] = v;
|
||||
});
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
return function () {
|
||||
unwatchers.forEach((listener) => listener());
|
||||
};
|
||||
};
|
||||
|
||||
function normalizeExpression($scope, expr) {
|
||||
if (!expr) return;
|
||||
const norm = {
|
||||
fn: $scope.$watch,
|
||||
deep: false,
|
||||
};
|
||||
|
||||
if (_.isFunction(expr)) return _.assign(norm, { get: expr });
|
||||
if (_.isObject(expr)) return _.assign(norm, expr);
|
||||
if (!_.isString(expr)) return;
|
||||
|
||||
if (expr.substr(0, 2) === '[]') {
|
||||
return _.assign(norm, {
|
||||
fn: $scope.$watchCollection,
|
||||
get: expr.substr(2),
|
||||
});
|
||||
}
|
||||
|
||||
if (expr.charAt(0) === '=') {
|
||||
return _.assign(norm, {
|
||||
deep: true,
|
||||
get: expr.substr(1),
|
||||
});
|
||||
}
|
||||
|
||||
return _.assign(norm, { get: expr });
|
||||
}
|
||||
|
||||
return $delegate;
|
||||
});
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
/* eslint-disable */
|
||||
|
||||
import angular from 'angular';
|
||||
|
||||
export function initBindHtml() {
|
||||
angular
|
||||
.module('ui.bootstrap.bindHtml', [])
|
||||
|
||||
.directive('bindHtmlUnsafe', function() {
|
||||
return function(scope, element, attr) {
|
||||
element.addClass('ng-binding').data('$binding', attr.bindHtmlUnsafe);
|
||||
scope.$watch(attr.bindHtmlUnsafe, function bindHtmlUnsafeWatchAction(value) {
|
||||
element.html(value || '');
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/* eslint-disable */
|
||||
|
||||
import { once } from 'lodash';
|
||||
import angular from 'angular';
|
||||
|
||||
// @ts-ignore
|
||||
import { initBindHtml } from './bind_html/bind_html';
|
||||
// @ts-ignore
|
||||
import { initBootstrapTooltip } from './tooltip/tooltip';
|
||||
|
||||
import tooltipPopup from './tooltip/tooltip_popup.html';
|
||||
|
||||
import tooltipUnsafePopup from './tooltip/tooltip_html_unsafe_popup.html';
|
||||
|
||||
export const initAngularBootstrap = once(() => {
|
||||
/*
|
||||
* angular-ui-bootstrap
|
||||
* http://angular-ui.github.io/bootstrap/
|
||||
|
||||
* Version: 0.12.1 - 2015-02-20
|
||||
* License: MIT
|
||||
*/
|
||||
angular.module('ui.bootstrap', [
|
||||
'ui.bootstrap.tpls',
|
||||
'ui.bootstrap.bindHtml',
|
||||
'ui.bootstrap.tooltip',
|
||||
]);
|
||||
|
||||
angular.module('ui.bootstrap.tpls', [
|
||||
'template/tooltip/tooltip-html-unsafe-popup.html',
|
||||
'template/tooltip/tooltip-popup.html',
|
||||
]);
|
||||
|
||||
initBindHtml();
|
||||
initBootstrapTooltip();
|
||||
|
||||
angular.module('template/tooltip/tooltip-html-unsafe-popup.html', []).run([
|
||||
'$templateCache',
|
||||
function($templateCache: any) {
|
||||
$templateCache.put('template/tooltip/tooltip-html-unsafe-popup.html', tooltipUnsafePopup);
|
||||
},
|
||||
]);
|
||||
|
||||
angular.module('template/tooltip/tooltip-popup.html', []).run([
|
||||
'$templateCache',
|
||||
function($templateCache: any) {
|
||||
$templateCache.put('template/tooltip/tooltip-popup.html', tooltipPopup);
|
||||
},
|
||||
]);
|
||||
});
|
|
@ -1,167 +0,0 @@
|
|||
/* eslint-disable */
|
||||
|
||||
import angular from 'angular';
|
||||
|
||||
export function initBootstrapPosition() {
|
||||
angular
|
||||
.module('ui.bootstrap.position', [])
|
||||
|
||||
/**
|
||||
* A set of utility methods that can be use to retrieve position of DOM elements.
|
||||
* It is meant to be used where we need to absolute-position DOM elements in
|
||||
* relation to other, existing elements (this is the case for tooltips, popovers,
|
||||
* typeahead suggestions etc.).
|
||||
*/
|
||||
.factory('$position', [
|
||||
'$document',
|
||||
'$window',
|
||||
function($document, $window) {
|
||||
function getStyle(el, cssprop) {
|
||||
if (el.currentStyle) {
|
||||
//IE
|
||||
return el.currentStyle[cssprop];
|
||||
} else if ($window.getComputedStyle) {
|
||||
return $window.getComputedStyle(el)[cssprop];
|
||||
}
|
||||
// finally try and get inline style
|
||||
return el.style[cssprop];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a given element is statically positioned
|
||||
* @param element - raw DOM element
|
||||
*/
|
||||
function isStaticPositioned(element) {
|
||||
return (getStyle(element, 'position') || 'static') === 'static';
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the closest, non-statically positioned parentOffset of a given element
|
||||
* @param element
|
||||
*/
|
||||
const parentOffsetEl = function(element) {
|
||||
const docDomEl = $document[0];
|
||||
let offsetParent = element.offsetParent || docDomEl;
|
||||
while (offsetParent && offsetParent !== docDomEl && isStaticPositioned(offsetParent)) {
|
||||
offsetParent = offsetParent.offsetParent;
|
||||
}
|
||||
return offsetParent || docDomEl;
|
||||
};
|
||||
|
||||
return {
|
||||
/**
|
||||
* Provides read-only equivalent of jQuery's position function:
|
||||
* http://api.jquery.com/position/
|
||||
*/
|
||||
position: function(element) {
|
||||
const elBCR = this.offset(element);
|
||||
let offsetParentBCR = { top: 0, left: 0 };
|
||||
const offsetParentEl = parentOffsetEl(element[0]);
|
||||
if (offsetParentEl != $document[0]) {
|
||||
offsetParentBCR = this.offset(angular.element(offsetParentEl));
|
||||
offsetParentBCR.top += offsetParentEl.clientTop - offsetParentEl.scrollTop;
|
||||
offsetParentBCR.left += offsetParentEl.clientLeft - offsetParentEl.scrollLeft;
|
||||
}
|
||||
|
||||
const boundingClientRect = element[0].getBoundingClientRect();
|
||||
return {
|
||||
width: boundingClientRect.width || element.prop('offsetWidth'),
|
||||
height: boundingClientRect.height || element.prop('offsetHeight'),
|
||||
top: elBCR.top - offsetParentBCR.top,
|
||||
left: elBCR.left - offsetParentBCR.left,
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Provides read-only equivalent of jQuery's offset function:
|
||||
* http://api.jquery.com/offset/
|
||||
*/
|
||||
offset: function(element) {
|
||||
const boundingClientRect = element[0].getBoundingClientRect();
|
||||
return {
|
||||
width: boundingClientRect.width || element.prop('offsetWidth'),
|
||||
height: boundingClientRect.height || element.prop('offsetHeight'),
|
||||
top:
|
||||
boundingClientRect.top +
|
||||
($window.pageYOffset || $document[0].documentElement.scrollTop),
|
||||
left:
|
||||
boundingClientRect.left +
|
||||
($window.pageXOffset || $document[0].documentElement.scrollLeft),
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Provides coordinates for the targetEl in relation to hostEl
|
||||
*/
|
||||
positionElements: function(hostEl, targetEl, positionStr, appendToBody) {
|
||||
const positionStrParts = positionStr.split('-');
|
||||
const pos0 = positionStrParts[0];
|
||||
const pos1 = positionStrParts[1] || 'center';
|
||||
|
||||
let hostElPos;
|
||||
let targetElWidth;
|
||||
let targetElHeight;
|
||||
let targetElPos;
|
||||
|
||||
hostElPos = appendToBody ? this.offset(hostEl) : this.position(hostEl);
|
||||
|
||||
targetElWidth = targetEl.prop('offsetWidth');
|
||||
targetElHeight = targetEl.prop('offsetHeight');
|
||||
|
||||
const shiftWidth = {
|
||||
center: function() {
|
||||
return hostElPos.left + hostElPos.width / 2 - targetElWidth / 2;
|
||||
},
|
||||
left: function() {
|
||||
return hostElPos.left;
|
||||
},
|
||||
right: function() {
|
||||
return hostElPos.left + hostElPos.width;
|
||||
},
|
||||
};
|
||||
|
||||
const shiftHeight = {
|
||||
center: function() {
|
||||
return hostElPos.top + hostElPos.height / 2 - targetElHeight / 2;
|
||||
},
|
||||
top: function() {
|
||||
return hostElPos.top;
|
||||
},
|
||||
bottom: function() {
|
||||
return hostElPos.top + hostElPos.height;
|
||||
},
|
||||
};
|
||||
|
||||
switch (pos0) {
|
||||
case 'right':
|
||||
targetElPos = {
|
||||
top: shiftHeight[pos1](),
|
||||
left: shiftWidth[pos0](),
|
||||
};
|
||||
break;
|
||||
case 'left':
|
||||
targetElPos = {
|
||||
top: shiftHeight[pos1](),
|
||||
left: hostElPos.left - targetElWidth,
|
||||
};
|
||||
break;
|
||||
case 'bottom':
|
||||
targetElPos = {
|
||||
top: shiftHeight[pos0](),
|
||||
left: shiftWidth[pos1](),
|
||||
};
|
||||
break;
|
||||
default:
|
||||
targetElPos = {
|
||||
top: hostElPos.top - targetElHeight,
|
||||
left: shiftWidth[pos1](),
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
return targetElPos;
|
||||
},
|
||||
};
|
||||
},
|
||||
]);
|
||||
}
|
|
@ -1,423 +0,0 @@
|
|||
/* eslint-disable */
|
||||
|
||||
import angular from 'angular';
|
||||
|
||||
import { initBootstrapPosition } from './position';
|
||||
|
||||
export function initBootstrapTooltip() {
|
||||
initBootstrapPosition();
|
||||
/**
|
||||
* The following features are still outstanding: animation as a
|
||||
* function, placement as a function, inside, support for more triggers than
|
||||
* just mouse enter/leave, html tooltips, and selector delegation.
|
||||
*/
|
||||
angular
|
||||
.module('ui.bootstrap.tooltip', ['ui.bootstrap.position'])
|
||||
|
||||
/**
|
||||
* The $tooltip service creates tooltip- and popover-like directives as well as
|
||||
* houses global options for them.
|
||||
*/
|
||||
.provider('$tooltip', function() {
|
||||
// The default options tooltip and popover.
|
||||
const defaultOptions = {
|
||||
placement: 'top',
|
||||
animation: true,
|
||||
popupDelay: 0,
|
||||
};
|
||||
|
||||
// Default hide triggers for each show trigger
|
||||
const triggerMap = {
|
||||
mouseenter: 'mouseleave',
|
||||
click: 'click',
|
||||
focus: 'blur',
|
||||
};
|
||||
|
||||
// The options specified to the provider globally.
|
||||
const globalOptions = {};
|
||||
|
||||
/**
|
||||
* `options({})` allows global configuration of all tooltips in the
|
||||
* application.
|
||||
*
|
||||
* var app = angular.module( 'App', ['ui.bootstrap.tooltip'], function( $tooltipProvider ) {
|
||||
* // place tooltips left instead of top by default
|
||||
* $tooltipProvider.options( { placement: 'left' } );
|
||||
* });
|
||||
*/
|
||||
this.options = function(value) {
|
||||
angular.extend(globalOptions, value);
|
||||
};
|
||||
|
||||
/**
|
||||
* This allows you to extend the set of trigger mappings available. E.g.:
|
||||
*
|
||||
* $tooltipProvider.setTriggers( 'openTrigger': 'closeTrigger' );
|
||||
*/
|
||||
this.setTriggers = function setTriggers(triggers) {
|
||||
angular.extend(triggerMap, triggers);
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a helper function for translating camel-case to snake-case.
|
||||
*/
|
||||
function snake_case(name) {
|
||||
const regexp = /[A-Z]/g;
|
||||
const separator = '-';
|
||||
return name.replace(regexp, function(letter, pos) {
|
||||
return (pos ? separator : '') + letter.toLowerCase();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the actual instance of the $tooltip service.
|
||||
* TODO support multiple triggers
|
||||
*/
|
||||
this.$get = [
|
||||
'$window',
|
||||
'$compile',
|
||||
'$timeout',
|
||||
'$document',
|
||||
'$position',
|
||||
'$interpolate',
|
||||
function($window, $compile, $timeout, $document, $position, $interpolate) {
|
||||
return function $tooltip(type, prefix, defaultTriggerShow) {
|
||||
const options = angular.extend({}, defaultOptions, globalOptions);
|
||||
|
||||
/**
|
||||
* Returns an object of show and hide triggers.
|
||||
*
|
||||
* If a trigger is supplied,
|
||||
* it is used to show the tooltip; otherwise, it will use the `trigger`
|
||||
* option passed to the `$tooltipProvider.options` method; else it will
|
||||
* default to the trigger supplied to this directive factory.
|
||||
*
|
||||
* The hide trigger is based on the show trigger. If the `trigger` option
|
||||
* was passed to the `$tooltipProvider.options` method, it will use the
|
||||
* mapped trigger from `triggerMap` or the passed trigger if the map is
|
||||
* undefined; otherwise, it uses the `triggerMap` value of the show
|
||||
* trigger; else it will just use the show trigger.
|
||||
*/
|
||||
function getTriggers(trigger) {
|
||||
const show = trigger || options.trigger || defaultTriggerShow;
|
||||
const hide = triggerMap[show] || show;
|
||||
return {
|
||||
show: show,
|
||||
hide: hide,
|
||||
};
|
||||
}
|
||||
|
||||
const directiveName = snake_case(type);
|
||||
|
||||
const startSym = $interpolate.startSymbol();
|
||||
const endSym = $interpolate.endSymbol();
|
||||
const template =
|
||||
'<div ' +
|
||||
directiveName +
|
||||
'-popup ' +
|
||||
'title="' +
|
||||
startSym +
|
||||
'title' +
|
||||
endSym +
|
||||
'" ' +
|
||||
'content="' +
|
||||
startSym +
|
||||
'content' +
|
||||
endSym +
|
||||
'" ' +
|
||||
'placement="' +
|
||||
startSym +
|
||||
'placement' +
|
||||
endSym +
|
||||
'" ' +
|
||||
'animation="animation" ' +
|
||||
'is-open="isOpen"' +
|
||||
'>' +
|
||||
'</div>';
|
||||
|
||||
return {
|
||||
restrict: 'EA',
|
||||
compile: function(tElem, tAttrs) {
|
||||
const tooltipLinker = $compile(template);
|
||||
|
||||
return function link(scope, element, attrs) {
|
||||
let tooltip;
|
||||
let tooltipLinkedScope;
|
||||
let transitionTimeout;
|
||||
let popupTimeout;
|
||||
let appendToBody = angular.isDefined(options.appendToBody)
|
||||
? options.appendToBody
|
||||
: false;
|
||||
let triggers = getTriggers(undefined);
|
||||
const hasEnableExp = angular.isDefined(attrs[prefix + 'Enable']);
|
||||
let ttScope = scope.$new(true);
|
||||
|
||||
const positionTooltip = function() {
|
||||
const ttPosition = $position.positionElements(
|
||||
element,
|
||||
tooltip,
|
||||
ttScope.placement,
|
||||
appendToBody
|
||||
);
|
||||
ttPosition.top += 'px';
|
||||
ttPosition.left += 'px';
|
||||
|
||||
// Now set the calculated positioning.
|
||||
tooltip.css(ttPosition);
|
||||
};
|
||||
|
||||
// By default, the tooltip is not open.
|
||||
// TODO add ability to start tooltip opened
|
||||
ttScope.isOpen = false;
|
||||
|
||||
function toggleTooltipBind() {
|
||||
if (!ttScope.isOpen) {
|
||||
showTooltipBind();
|
||||
} else {
|
||||
hideTooltipBind();
|
||||
}
|
||||
}
|
||||
|
||||
// Show the tooltip with delay if specified, otherwise show it immediately
|
||||
function showTooltipBind() {
|
||||
if (hasEnableExp && !scope.$eval(attrs[prefix + 'Enable'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
prepareTooltip();
|
||||
|
||||
if (ttScope.popupDelay) {
|
||||
// Do nothing if the tooltip was already scheduled to pop-up.
|
||||
// This happens if show is triggered multiple times before any hide is triggered.
|
||||
if (!popupTimeout) {
|
||||
popupTimeout = $timeout(show, ttScope.popupDelay, false);
|
||||
popupTimeout
|
||||
.then(reposition => reposition())
|
||||
.catch(error => {
|
||||
// if the timeout is canceled then the string `canceled` is thrown. To prevent
|
||||
// this from triggering an 'unhandled promise rejection' in angular 1.5+ the
|
||||
// $timeout service explicitly tells $q that the promise it generated is "handled"
|
||||
// but that does not include down chain promises like the one created by calling
|
||||
// `popupTimeout.then()`. Because of this we need to ignore the "canceled" string
|
||||
// and only propagate real errors
|
||||
if (error !== 'canceled') {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
show()();
|
||||
}
|
||||
}
|
||||
|
||||
function hideTooltipBind() {
|
||||
scope.$evalAsync(function() {
|
||||
hide();
|
||||
});
|
||||
}
|
||||
|
||||
// Show the tooltip popup element.
|
||||
function show() {
|
||||
popupTimeout = null;
|
||||
|
||||
// If there is a pending remove transition, we must cancel it, lest the
|
||||
// tooltip be mysteriously removed.
|
||||
if (transitionTimeout) {
|
||||
$timeout.cancel(transitionTimeout);
|
||||
transitionTimeout = null;
|
||||
}
|
||||
|
||||
// Don't show empty tooltips.
|
||||
if (!ttScope.content) {
|
||||
return angular.noop;
|
||||
}
|
||||
|
||||
createTooltip();
|
||||
|
||||
// Set the initial positioning.
|
||||
tooltip.css({ top: 0, left: 0, display: 'block' });
|
||||
ttScope.$digest();
|
||||
|
||||
positionTooltip();
|
||||
|
||||
// And show the tooltip.
|
||||
ttScope.isOpen = true;
|
||||
ttScope.$digest(); // digest required as $apply is not called
|
||||
|
||||
// Return positioning function as promise callback for correct
|
||||
// positioning after draw.
|
||||
return positionTooltip;
|
||||
}
|
||||
|
||||
// Hide the tooltip popup element.
|
||||
function hide() {
|
||||
// First things first: we don't show it anymore.
|
||||
ttScope.isOpen = false;
|
||||
|
||||
//if tooltip is going to be shown after delay, we must cancel this
|
||||
$timeout.cancel(popupTimeout);
|
||||
popupTimeout = null;
|
||||
|
||||
// And now we remove it from the DOM. However, if we have animation, we
|
||||
// need to wait for it to expire beforehand.
|
||||
// FIXME: this is a placeholder for a port of the transitions library.
|
||||
if (ttScope.animation) {
|
||||
if (!transitionTimeout) {
|
||||
transitionTimeout = $timeout(removeTooltip, 500);
|
||||
}
|
||||
} else {
|
||||
removeTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
function createTooltip() {
|
||||
// There can only be one tooltip element per directive shown at once.
|
||||
if (tooltip) {
|
||||
removeTooltip();
|
||||
}
|
||||
tooltipLinkedScope = ttScope.$new();
|
||||
tooltip = tooltipLinker(tooltipLinkedScope, function(tooltip) {
|
||||
if (appendToBody) {
|
||||
$document.find('body').append(tooltip);
|
||||
} else {
|
||||
element.after(tooltip);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function removeTooltip() {
|
||||
transitionTimeout = null;
|
||||
if (tooltip) {
|
||||
tooltip.remove();
|
||||
tooltip = null;
|
||||
}
|
||||
if (tooltipLinkedScope) {
|
||||
tooltipLinkedScope.$destroy();
|
||||
tooltipLinkedScope = null;
|
||||
}
|
||||
}
|
||||
|
||||
function prepareTooltip() {
|
||||
prepPlacement();
|
||||
prepPopupDelay();
|
||||
}
|
||||
|
||||
/**
|
||||
* Observe the relevant attributes.
|
||||
*/
|
||||
attrs.$observe(type, function(val) {
|
||||
ttScope.content = val;
|
||||
|
||||
if (!val && ttScope.isOpen) {
|
||||
hide();
|
||||
}
|
||||
});
|
||||
|
||||
attrs.$observe(prefix + 'Title', function(val) {
|
||||
ttScope.title = val;
|
||||
});
|
||||
|
||||
function prepPlacement() {
|
||||
const val = attrs[prefix + 'Placement'];
|
||||
ttScope.placement = angular.isDefined(val) ? val : options.placement;
|
||||
}
|
||||
|
||||
function prepPopupDelay() {
|
||||
const val = attrs[prefix + 'PopupDelay'];
|
||||
const delay = parseInt(val, 10);
|
||||
ttScope.popupDelay = !isNaN(delay) ? delay : options.popupDelay;
|
||||
}
|
||||
|
||||
const unregisterTriggers = function() {
|
||||
element.unbind(triggers.show, showTooltipBind);
|
||||
element.unbind(triggers.hide, hideTooltipBind);
|
||||
};
|
||||
|
||||
function prepTriggers() {
|
||||
const val = attrs[prefix + 'Trigger'];
|
||||
unregisterTriggers();
|
||||
|
||||
triggers = getTriggers(val);
|
||||
|
||||
if (triggers.show === triggers.hide) {
|
||||
element.bind(triggers.show, toggleTooltipBind);
|
||||
} else {
|
||||
element.bind(triggers.show, showTooltipBind);
|
||||
element.bind(triggers.hide, hideTooltipBind);
|
||||
}
|
||||
}
|
||||
|
||||
prepTriggers();
|
||||
|
||||
const animation = scope.$eval(attrs[prefix + 'Animation']);
|
||||
ttScope.animation = angular.isDefined(animation)
|
||||
? !!animation
|
||||
: options.animation;
|
||||
|
||||
const appendToBodyVal = scope.$eval(attrs[prefix + 'AppendToBody']);
|
||||
appendToBody = angular.isDefined(appendToBodyVal)
|
||||
? appendToBodyVal
|
||||
: appendToBody;
|
||||
|
||||
// if a tooltip is attached to <body> we need to remove it on
|
||||
// location change as its parent scope will probably not be destroyed
|
||||
// by the change.
|
||||
if (appendToBody) {
|
||||
scope.$on(
|
||||
'$locationChangeSuccess',
|
||||
function closeTooltipOnLocationChangeSuccess() {
|
||||
if (ttScope.isOpen) {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Make sure tooltip is destroyed and removed.
|
||||
scope.$on('$destroy', function onDestroyTooltip() {
|
||||
$timeout.cancel(transitionTimeout);
|
||||
$timeout.cancel(popupTimeout);
|
||||
unregisterTriggers();
|
||||
removeTooltip();
|
||||
ttScope = null;
|
||||
});
|
||||
};
|
||||
},
|
||||
};
|
||||
};
|
||||
},
|
||||
];
|
||||
})
|
||||
|
||||
.directive('tooltip', [
|
||||
'$tooltip',
|
||||
function($tooltip) {
|
||||
return $tooltip('tooltip', 'tooltip', 'mouseenter');
|
||||
},
|
||||
])
|
||||
|
||||
.directive('tooltipPopup', function() {
|
||||
return {
|
||||
restrict: 'EA',
|
||||
replace: true,
|
||||
scope: { content: '@', placement: '@', animation: '&', isOpen: '&' },
|
||||
templateUrl: 'template/tooltip/tooltip-popup.html',
|
||||
};
|
||||
})
|
||||
|
||||
.directive('tooltipHtmlUnsafe', [
|
||||
'$tooltip',
|
||||
function($tooltip) {
|
||||
return $tooltip('tooltipHtmlUnsafe', 'tooltip', 'mouseenter');
|
||||
},
|
||||
])
|
||||
|
||||
.directive('tooltipHtmlUnsafePopup', function() {
|
||||
return {
|
||||
restrict: 'EA',
|
||||
replace: true,
|
||||
scope: { content: '@', placement: '@', animation: '&', isOpen: '&' },
|
||||
templateUrl: 'template/tooltip/tooltip-html-unsafe-popup.html',
|
||||
};
|
||||
});
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
<div class="bsTooltip {{placement}}" ng-class="{ in: isOpen(), fade: animation() }">
|
||||
<div class="bsTooltip-arrow"></div>
|
||||
<div class="bsTooltip-inner" bind-html-unsafe="content"></div>
|
||||
</div>
|
|
@ -1,4 +0,0 @@
|
|||
<div class="bsTooltip {{placement}}" ng-class="{ in: isOpen(), fade: animation() }">
|
||||
<div class="bsTooltip-arrow"></div>
|
||||
<div class="bsTooltip-inner" ng-bind="content"></div>
|
||||
</div>
|
|
@ -15,7 +15,6 @@ export const plugin = () => new KibanaLegacyPlugin();
|
|||
|
||||
export * from './plugin';
|
||||
|
||||
export { PaginateDirectiveProvider, PaginateControlsDirectiveProvider } from './paginate/paginate';
|
||||
export * from './angular';
|
||||
export * from './notify';
|
||||
export * from './utils';
|
||||
|
|
|
@ -15,7 +15,6 @@ const createSetupContract = (): Setup => ({});
|
|||
|
||||
const createStartContract = (): Start => ({
|
||||
loadFontAwesome: jest.fn(),
|
||||
loadAngularBootstrap: jest.fn(),
|
||||
});
|
||||
|
||||
export const kibanaLegacyPluginMock = {
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { FatalErrorsSetup } from '../../../../../core/public';
|
||||
import {
|
||||
AngularHttpError,
|
||||
formatAngularHttpError,
|
||||
isAngularHttpError,
|
||||
} from './format_angular_http_error';
|
||||
|
||||
export function addFatalError(
|
||||
fatalErrors: FatalErrorsSetup,
|
||||
error: AngularHttpError | Error | string,
|
||||
location?: string
|
||||
) {
|
||||
// add support for angular http errors to newPlatformFatalErrors
|
||||
if (isAngularHttpError(error)) {
|
||||
error = formatAngularHttpError(error);
|
||||
}
|
||||
|
||||
fatalErrors.add(error, location);
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
// browsers format Error.stack differently; always include message
|
||||
export function formatStack(err: Record<string, any>) {
|
||||
if (err.stack && err.stack.indexOf(err.message) === -1) {
|
||||
return i18n.translate('kibana_legacy.notify.toaster.errorMessage', {
|
||||
defaultMessage: `Error: {errorMessage}
|
||||
{errorStack}`,
|
||||
values: {
|
||||
errorMessage: err.message,
|
||||
errorStack: err.stack,
|
||||
},
|
||||
});
|
||||
}
|
||||
return err.stack;
|
||||
}
|
|
@ -8,10 +8,8 @@
|
|||
|
||||
export { formatESMsg } from './format_es_msg';
|
||||
export { formatMsg } from './format_msg';
|
||||
export { formatStack } from './format_stack';
|
||||
export {
|
||||
isAngularHttpError,
|
||||
formatAngularHttpError,
|
||||
AngularHttpError,
|
||||
} from './format_angular_http_error';
|
||||
export { addFatalError } from './add_fatal_error';
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
paginate {
|
||||
display: block;
|
||||
|
||||
paginate-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: $euiSizeXS $euiSizeXS $euiSizeS;
|
||||
text-align: center;
|
||||
|
||||
.pagination-other-pages {
|
||||
flex: 1 0 auto;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.pagination-other-pages-list {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
|
||||
> li {
|
||||
flex: 0 0 auto;
|
||||
user-select: none;
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
background-color: $euiColorLightestShade;
|
||||
margin-left: $euiSizeXS / 2;
|
||||
padding: $euiSizeS $euiSizeM;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
&.active a { // stylelint-disable-line selector-no-qualifying-type
|
||||
text-decoration: none !important;
|
||||
font-weight: $euiFontWeightBold;
|
||||
color: $euiColorDarkShade;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pagination-size {
|
||||
flex: 0 0 auto;
|
||||
|
||||
input[type=number] {
|
||||
width: 3em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export function PaginateDirectiveProvider($parse: any, $compile: any): any;
|
||||
export function PaginateControlsDirectiveProvider(): any;
|
|
@ -1,217 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import _ from 'lodash';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import './_paginate.scss';
|
||||
import paginateControlsTemplate from './paginate_controls.html';
|
||||
|
||||
export function PaginateDirectiveProvider($parse, $compile) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: true,
|
||||
link: {
|
||||
pre: function ($scope, $el, attrs) {
|
||||
if (_.isUndefined(attrs.bottomControls)) attrs.bottomControls = true;
|
||||
if ($el.find('paginate-controls.paginate-bottom').length === 0 && attrs.bottomControls) {
|
||||
$el.append($compile('<paginate-controls class="paginate-bottom">')($scope));
|
||||
}
|
||||
},
|
||||
post: function ($scope, $el, attrs) {
|
||||
if (_.isUndefined(attrs.topControls)) attrs.topControls = false;
|
||||
if ($el.find('paginate-controls.paginate-top').length === 0 && attrs.topControls) {
|
||||
$el.prepend($compile('<paginate-controls class="paginate-top">')($scope));
|
||||
}
|
||||
|
||||
const paginate = $scope.paginate;
|
||||
|
||||
// add some getters to the controller powered by attributes
|
||||
paginate.getList = $parse(attrs.list);
|
||||
paginate.perPageProp = attrs.perPageProp;
|
||||
|
||||
if (attrs.perPage) {
|
||||
paginate.perPage = attrs.perPage;
|
||||
$scope.showSelector = false;
|
||||
} else {
|
||||
$scope.showSelector = true;
|
||||
}
|
||||
|
||||
paginate.otherWidthGetter = $parse(attrs.otherWidth);
|
||||
|
||||
paginate.init();
|
||||
},
|
||||
},
|
||||
controllerAs: 'paginate',
|
||||
controller: function ($scope, $document) {
|
||||
const self = this;
|
||||
const ALL = 0;
|
||||
const allSizeTitle = i18n.translate('kibana_legacy.paginate.size.allDropDownOptionLabel', {
|
||||
defaultMessage: 'All',
|
||||
});
|
||||
|
||||
self.sizeOptions = [
|
||||
{ title: '10', value: 10 },
|
||||
{ title: '25', value: 25 },
|
||||
{ title: '100', value: 100 },
|
||||
{ title: allSizeTitle, value: ALL },
|
||||
];
|
||||
|
||||
// setup the watchers, called in the post-link function
|
||||
self.init = function () {
|
||||
self.perPage = _.parseInt(self.perPage) || $scope[self.perPageProp];
|
||||
|
||||
$scope.$watchMulti(
|
||||
['paginate.perPage', self.perPageProp, self.otherWidthGetter],
|
||||
function (vals, oldVals) {
|
||||
const intChanges = vals[0] !== oldVals[0];
|
||||
|
||||
if (intChanges) {
|
||||
if (!setPerPage(self.perPage)) {
|
||||
// if we are not able to set the external value,
|
||||
// render now, otherwise wait for the external value
|
||||
// to trigger the watcher again
|
||||
self.renderList();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
self.perPage = _.parseInt(self.perPage) || $scope[self.perPageProp];
|
||||
if (self.perPage == null) {
|
||||
self.perPage = ALL;
|
||||
return;
|
||||
}
|
||||
|
||||
self.renderList();
|
||||
}
|
||||
);
|
||||
|
||||
$scope.$watch('page', self.changePage);
|
||||
$scope.$watchCollection(self.getList, function (list) {
|
||||
$scope.list = list;
|
||||
self.renderList();
|
||||
});
|
||||
};
|
||||
|
||||
self.goToPage = function (number) {
|
||||
if (number) {
|
||||
if (number.hasOwnProperty('number')) number = number.number;
|
||||
$scope.page = $scope.pages[number - 1] || $scope.pages[0];
|
||||
}
|
||||
};
|
||||
|
||||
self.goToTop = function goToTop() {
|
||||
$document.scrollTop(0);
|
||||
};
|
||||
|
||||
self.renderList = function () {
|
||||
$scope.pages = [];
|
||||
if (!$scope.list) return;
|
||||
|
||||
const perPage = _.parseInt(self.perPage);
|
||||
const count = perPage ? Math.ceil($scope.list.length / perPage) : 1;
|
||||
|
||||
_.times(count, function (i) {
|
||||
let page;
|
||||
|
||||
if (perPage) {
|
||||
const start = perPage * i;
|
||||
page = $scope.list.slice(start, start + perPage);
|
||||
} else {
|
||||
page = $scope.list.slice(0);
|
||||
}
|
||||
|
||||
page.number = i + 1;
|
||||
page.i = i;
|
||||
|
||||
page.count = count;
|
||||
page.first = page.number === 1;
|
||||
page.last = page.number === count;
|
||||
page.firstItem = (page.number - 1) * perPage + 1;
|
||||
page.lastItem = Math.min(page.number * perPage, $scope.list.length);
|
||||
|
||||
page.prev = $scope.pages[i - 1];
|
||||
if (page.prev) page.prev.next = page;
|
||||
|
||||
$scope.pages.push(page);
|
||||
});
|
||||
|
||||
// set the new page, or restore the previous page number
|
||||
if ($scope.page && $scope.page.i < $scope.pages.length) {
|
||||
$scope.page = $scope.pages[$scope.page.i];
|
||||
} else {
|
||||
$scope.page = $scope.pages[0];
|
||||
}
|
||||
|
||||
if ($scope.page && $scope.onPageChanged) {
|
||||
$scope.onPageChanged($scope.page);
|
||||
}
|
||||
};
|
||||
|
||||
self.changePage = function (page) {
|
||||
if (!page) {
|
||||
$scope.otherPages = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// setup the list of the other pages to link to
|
||||
$scope.otherPages = [];
|
||||
const width = +self.otherWidthGetter($scope) || 5;
|
||||
let left = page.i - Math.round((width - 1) / 2);
|
||||
let right = left + width - 1;
|
||||
|
||||
// shift neg count from left to right
|
||||
if (left < 0) {
|
||||
right += 0 - left;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
// shift extra right nums to left
|
||||
const lastI = page.count - 1;
|
||||
if (right > lastI) {
|
||||
right = lastI;
|
||||
left = right - width + 1;
|
||||
}
|
||||
|
||||
for (let i = left; i <= right; i++) {
|
||||
const other = $scope.pages[i];
|
||||
|
||||
if (!other) continue;
|
||||
|
||||
$scope.otherPages.push(other);
|
||||
if (other.last) $scope.otherPages.containsLast = true;
|
||||
if (other.first) $scope.otherPages.containsFirst = true;
|
||||
}
|
||||
|
||||
if ($scope.onPageChanged) {
|
||||
$scope.onPageChanged($scope.page);
|
||||
}
|
||||
};
|
||||
|
||||
function setPerPage(val) {
|
||||
let $ppParent = $scope;
|
||||
|
||||
while ($ppParent && !_.has($ppParent, self.perPageProp)) {
|
||||
$ppParent = $ppParent.$parent;
|
||||
}
|
||||
|
||||
if ($ppParent) {
|
||||
$ppParent[self.perPageProp] = val;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function PaginateControlsDirectiveProvider() {
|
||||
// this directive is automatically added by paginate if not found within it's $el
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: paginateControlsTemplate,
|
||||
};
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
<button
|
||||
class="kuiLink"
|
||||
ng-if="linkToTop"
|
||||
ng-click="paginate.goToTop()"
|
||||
data-test-subj="paginateControlsLinkToTop"
|
||||
i18n-id="kibana_legacy.paginate.controls.scrollTopButtonLabel"
|
||||
i18n-default-message="Scroll to top"
|
||||
></button>
|
||||
|
||||
<div
|
||||
class="pagination-other-pages"
|
||||
data-test-subj="paginationControls"
|
||||
>
|
||||
<ul class="pagination-other-pages-list pagination-sm" ng-if="page.count > 1">
|
||||
<li ng-style="{'visibility':'hidden'}" ng-if="page.first">
|
||||
<button
|
||||
class="euiButtonEmpty euiButtonEmpty--text euiButtonEmpty--small euiPaginationButton"
|
||||
ng-click="paginate.goToPage(page.prev)"
|
||||
>
|
||||
<span class="euiButtonEmpty__content">«</span>
|
||||
</button>
|
||||
</li>
|
||||
<li ng-style="{'visibility':'visible'}" ng-if="!page.first">
|
||||
<button
|
||||
class="euiButtonEmpty euiButtonEmpty--text euiButtonEmpty--small euiPaginationButton"
|
||||
ng-click="paginate.goToPage(page.prev)"
|
||||
>
|
||||
<span class="euiButtonEmpty__content">«</span>
|
||||
</button>
|
||||
</li>
|
||||
|
||||
<li ng-if="!otherPages.containsFirst">
|
||||
<button
|
||||
class="euiButtonEmpty euiButtonEmpty--text euiButtonEmpty--small euiPaginationButton"
|
||||
ng-click="paginate.goToPage(1)"
|
||||
>
|
||||
<span class="euiButtonEmpty__content">1</span>
|
||||
</button>
|
||||
...
|
||||
</li>
|
||||
|
||||
<li
|
||||
ng-repeat="other in otherPages"
|
||||
ng-class="{ active: other.number === page.number }"
|
||||
>
|
||||
<button
|
||||
class="euiButtonEmpty euiButtonEmpty--text euiButtonEmpty--small euiPaginationButton"
|
||||
ng-class="{ 'euiPaginationButton-isActive': other.number === page.number }"
|
||||
ng-click="paginate.goToPage(other)"
|
||||
>
|
||||
<span class="euiButtonEmpty__content">{{other.number}}</span>
|
||||
</button>
|
||||
</li>
|
||||
|
||||
<li ng-if="!otherPages.containsLast">
|
||||
...
|
||||
<button
|
||||
class="euiButtonEmpty euiButtonEmpty--text euiButtonEmpty--small euiPaginationButton"
|
||||
ng-click="paginate.goToPage(page.count)"
|
||||
>
|
||||
<span class="euiButtonEmpty__content">{{page.count}}</span>
|
||||
</button>
|
||||
</li>
|
||||
|
||||
<li ng-style="{'visibility':'hidden'}" ng-if="page.last">
|
||||
<button
|
||||
class="euiButtonEmpty euiButtonEmpty--text euiButtonEmpty--small euiPaginationButton"
|
||||
data-test-subj="paginateNext"
|
||||
ng-click="paginate.goToPage(page.next)"
|
||||
>
|
||||
<span class="euiButtonEmpty__content">»</span>
|
||||
</button>
|
||||
</li>
|
||||
<li ng-style="{'visibility':'visible'}" ng-if="!page.last">
|
||||
<button
|
||||
class="euiButtonEmpty euiButtonEmpty--text euiButtonEmpty--small euiPaginationButton"
|
||||
data-test-subj="paginateNext"
|
||||
ng-click="paginate.goToPage(page.next)"
|
||||
>
|
||||
<span class="euiButtonEmpty__content">»</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<form class="form-inline pagination-size" ng-if="showSelector">
|
||||
<div class="form-group">
|
||||
<label
|
||||
i18n-id="kibana_legacy.paginate.controls.pageSizeLabel"
|
||||
i18n-default-message="Page Size"
|
||||
></label>
|
||||
<select
|
||||
ng-model="paginate.perPage"
|
||||
ng-options="opt.value as opt.title for opt in paginate.sizeOptions"
|
||||
data-test-subj="paginateControlsPageSizeSelect"
|
||||
></select>
|
||||
</div>
|
||||
</form>
|
|
@ -24,14 +24,6 @@ export class KibanaLegacyPlugin {
|
|||
loadFontAwesome: async () => {
|
||||
await import('./font_awesome');
|
||||
},
|
||||
/**
|
||||
* Loads angular bootstrap modules. Should be removed once the last consumer has migrated to EUI
|
||||
* @deprecated
|
||||
*/
|
||||
loadAngularBootstrap: async () => {
|
||||
const { initAngularBootstrap } = await import('./angular_bootstrap');
|
||||
initAngularBootstrap();
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,5 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
// @ts-ignore
|
||||
export { KbnAccessibleClickProvider } from './kbn_accessible_click';
|
||||
// @ts-ignore
|
||||
export { PrivateProvider, IPrivate } from './private';
|
||||
// @ts-ignore
|
||||
export { registerListenEventListener } from './register_listen_event_listener';
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { Injectable, IDirectiveFactory, IScope, IAttributes, IController } from 'angular';
|
||||
|
||||
export const KbnAccessibleClickProvider: Injectable<
|
||||
IDirectiveFactory<IScope, JQLite, IAttributes, IController>
|
||||
>;
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { accessibleClickKeys, keys } from '@elastic/eui';
|
||||
|
||||
export function KbnAccessibleClickProvider() {
|
||||
return {
|
||||
restrict: 'A',
|
||||
controller: ($element) => {
|
||||
$element.on('keydown', (e) => {
|
||||
// Prevent a scroll from occurring if the user has hit space.
|
||||
if (e.key === keys.SPACE) {
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
},
|
||||
link: (scope, element, attrs) => {
|
||||
// The whole point of this directive is to hack in functionality that native buttons provide
|
||||
// by default.
|
||||
const elementType = element.prop('tagName');
|
||||
|
||||
if (elementType === 'BUTTON') {
|
||||
throw new Error(`kbnAccessibleClick doesn't need to be used on a button.`);
|
||||
}
|
||||
|
||||
if (elementType === 'A' && attrs.href !== undefined) {
|
||||
throw new Error(
|
||||
`kbnAccessibleClick doesn't need to be used on a link if it has a href attribute.`
|
||||
);
|
||||
}
|
||||
|
||||
// We're emulating a click action, so we should already have a regular click handler defined.
|
||||
if (!attrs.ngClick) {
|
||||
throw new Error('kbnAccessibleClick requires ng-click to be defined on its element.');
|
||||
}
|
||||
|
||||
// If the developer hasn't already specified attributes required for accessibility, add them.
|
||||
if (attrs.tabindex === undefined) {
|
||||
element.attr('tabindex', '0');
|
||||
}
|
||||
|
||||
if (attrs.role === undefined) {
|
||||
element.attr('role', 'button');
|
||||
}
|
||||
|
||||
element.on('keyup', (e) => {
|
||||
// Support keyboard accessibility by emulating mouse click on ENTER or SPACE keypress.
|
||||
if (accessibleClickKeys[e.key]) {
|
||||
// Delegate to the click handler on the element (assumed to be ng-click).
|
||||
element.click();
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export function registerListenEventListener($rootScope: unknown): void;
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export function registerListenEventListener($rootScope) {
|
||||
/**
|
||||
* Helper that registers an event listener, and removes that listener when
|
||||
* the $scope is destroyed.
|
||||
*
|
||||
* @param {EventEmitter} emitter - the event emitter to listen to
|
||||
* @param {string} eventName - the event name
|
||||
* @param {Function} handler - the event handler
|
||||
* @return {undefined}
|
||||
*/
|
||||
$rootScope.constructor.prototype.$listen = function (emitter, eventName, handler) {
|
||||
emitter.on(eventName, handler);
|
||||
this.$on('$destroy', function () {
|
||||
emitter.off(eventName, handler);
|
||||
});
|
||||
};
|
||||
}
|
|
@ -6,8 +6,7 @@
|
|||
"requiredPlugins": [
|
||||
"expressions",
|
||||
"visualizations",
|
||||
"data",
|
||||
"kibanaLegacy"
|
||||
"data"
|
||||
],
|
||||
"requiredBundles": [
|
||||
"kibanaUtils",
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
{ "path": "../../usage_collection/tsconfig.json" },
|
||||
{ "path": "../../expressions/tsconfig.json" },
|
||||
{ "path": "../../kibana_utils/tsconfig.json" },
|
||||
{ "path": "../../kibana_legacy/tsconfig.json" },
|
||||
{ "path": "../../kibana_react/tsconfig.json" },
|
||||
{ "path": "../../vis_default_editor/tsconfig.json" },
|
||||
{ "path": "../../field_formats/tsconfig.json" }
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"server": true,
|
||||
"ui": true,
|
||||
"requiredPlugins": ["uiActions", "embeddable", "discover"],
|
||||
"optionalPlugins": ["share", "kibanaLegacy", "usageCollection"],
|
||||
"optionalPlugins": ["share", "usageCollection"],
|
||||
"configPath": ["xpack", "discoverEnhanced"],
|
||||
"requiredBundles": ["kibanaUtils", "data"],
|
||||
"owner": {
|
||||
|
|
|
@ -12,7 +12,6 @@ import { APPLY_FILTER_TRIGGER } from '../../../../src/plugins/data/public';
|
|||
import { createStartServicesGetter } from '../../../../src/plugins/kibana_utils/public';
|
||||
import { DiscoverSetup, DiscoverStart } from '../../../../src/plugins/discover/public';
|
||||
import { SharePluginSetup, SharePluginStart } from '../../../../src/plugins/share/public';
|
||||
import { KibanaLegacySetup, KibanaLegacyStart } from '../../../../src/plugins/kibana_legacy/public';
|
||||
import {
|
||||
EmbeddableSetup,
|
||||
EmbeddableStart,
|
||||
|
@ -24,7 +23,6 @@ import { Config } from '../common';
|
|||
export interface DiscoverEnhancedSetupDependencies {
|
||||
discover: DiscoverSetup;
|
||||
embeddable: EmbeddableSetup;
|
||||
kibanaLegacy?: KibanaLegacySetup;
|
||||
share?: SharePluginSetup;
|
||||
uiActions: UiActionsSetup;
|
||||
}
|
||||
|
@ -32,7 +30,6 @@ export interface DiscoverEnhancedSetupDependencies {
|
|||
export interface DiscoverEnhancedStartDependencies {
|
||||
discover: DiscoverStart;
|
||||
embeddable: EmbeddableStart;
|
||||
kibanaLegacy?: KibanaLegacyStart;
|
||||
share?: SharePluginStart;
|
||||
uiActions: UiActionsStart;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
{ "path": "../../../src/plugins/data/tsconfig.json" },
|
||||
{ "path": "../../../src/plugins/discover/tsconfig.json" },
|
||||
{ "path": "../../../src/plugins/share/tsconfig.json" },
|
||||
{ "path": "../../../src/plugins/kibana_legacy/tsconfig.json" },
|
||||
{ "path": "../../../src/plugins/kibana_utils/tsconfig.json" },
|
||||
{ "path": "../../../src/plugins/url_forwarding/tsconfig.json" },
|
||||
{ "path": "../../../src/plugins/usage_collection/tsconfig.json" },
|
||||
|
|
|
@ -4182,12 +4182,8 @@
|
|||
"inspector.view": "{viewName} を表示",
|
||||
"kibana_legacy.notify.fatalError.errorStatusMessage": "エラー {errStatus} {errStatusText}: {errMessage}",
|
||||
"kibana_legacy.notify.fatalError.unavailableServerErrorMessage": "HTTP リクエストで接続に失敗しました。Kibana サーバーが実行されていて、ご使用のブラウザの接続が正常に動作していることを確認するか、システム管理者にお問い合わせください。",
|
||||
"kibana_legacy.notify.toaster.errorMessage": "エラー:{errorMessage}\n {errorStack}",
|
||||
"kibana_legacy.notify.toaster.errorStatusMessage": "エラー {errStatus} {errStatusText}: {errMessage}",
|
||||
"kibana_legacy.notify.toaster.unavailableServerErrorMessage": "HTTP リクエストで接続に失敗しました。Kibana サーバーが実行されていて、ご使用のブラウザの接続が正常に動作していることを確認するか、システム管理者にお問い合わせください。",
|
||||
"kibana_legacy.paginate.controls.pageSizeLabel": "ページサイズ",
|
||||
"kibana_legacy.paginate.controls.scrollTopButtonLabel": "最上部に移動",
|
||||
"kibana_legacy.paginate.size.allDropDownOptionLabel": "すべて",
|
||||
"kibana_utils.history.savedObjectIsMissingNotificationMessage": "保存されたオブジェクトがありません",
|
||||
"kibana_utils.stateManagement.stateHash.unableToRestoreUrlErrorMessage": "URL を完全に復元できません。共有機能を使用していることを確認してください。",
|
||||
"kibana_utils.stateManagement.stateHash.unableToStoreHistoryInSessionErrorMessage": "セッションがいっぱいで安全に削除できるアイテムが見つからないため、Kibana は履歴アイテムを保存できません。\n\nこれは大抵新規タブに移動することで解決されますが、より大きな問題が原因である可能性もあります。このメッセージが定期的に表示される場合は、{gitHubIssuesUrl} で問題を報告してください。",
|
||||
|
|
|
@ -4222,12 +4222,8 @@
|
|||
"inspector.view": "视图:{viewName}",
|
||||
"kibana_legacy.notify.fatalError.errorStatusMessage": "错误 {errStatus} {errStatusText}:{errMessage}",
|
||||
"kibana_legacy.notify.fatalError.unavailableServerErrorMessage": "HTTP 请求无法连接。请检查 Kibana 服务器是否正在运行以及您的浏览器是否具有有效的连接,或请联系您的系统管理员。",
|
||||
"kibana_legacy.notify.toaster.errorMessage": "错误:{errorMessage}\n {errorStack}",
|
||||
"kibana_legacy.notify.toaster.errorStatusMessage": "错误 {errStatus} {errStatusText}:{errMessage}",
|
||||
"kibana_legacy.notify.toaster.unavailableServerErrorMessage": "HTTP 请求无法连接。请检查 Kibana 服务器是否正在运行以及您的浏览器是否具有有效的连接,或请联系您的系统管理员。",
|
||||
"kibana_legacy.paginate.controls.pageSizeLabel": "页面大小",
|
||||
"kibana_legacy.paginate.controls.scrollTopButtonLabel": "滚动至顶部",
|
||||
"kibana_legacy.paginate.size.allDropDownOptionLabel": "全部",
|
||||
"kibana_utils.history.savedObjectIsMissingNotificationMessage": "已保存对象缺失",
|
||||
"kibana_utils.stateManagement.stateHash.unableToRestoreUrlErrorMessage": "无法完全还原 URL,请确保使用共享功能。",
|
||||
"kibana_utils.stateManagement.stateHash.unableToStoreHistoryInSessionErrorMessage": "Kibana 无法将历史记录项存储在您的会话中,因为其已满,另外,似乎没有任何可安全删除的项目。\n\n通常,这可以通过移到全新的选项卡来解决,但这种情况可能是由更大的问题造成。如果您定期看到这个消息,请在 {gitHubIssuesUrl} 报告问题。",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue