mirror of
https://github.com/elastic/kibana.git
synced 2025-06-28 03:01:21 -04:00
[prettier] upgrade to 1.18.2 (#40229)
* [prettier] upgrade to 1.18.2 * autofix prettier violations
This commit is contained in:
parent
d818a2cd32
commit
a95ae8c037
197 changed files with 1451 additions and 1983 deletions
|
@ -359,7 +359,7 @@
|
||||||
"enzyme-adapter-utils": "^1.12.0",
|
"enzyme-adapter-utils": "^1.12.0",
|
||||||
"enzyme-to-json": "^3.3.4",
|
"enzyme-to-json": "^3.3.4",
|
||||||
"eslint": "5.16.0",
|
"eslint": "5.16.0",
|
||||||
"eslint-config-prettier": "4.3.0",
|
"eslint-config-prettier": "6.0.0",
|
||||||
"eslint-plugin-babel": "5.3.0",
|
"eslint-plugin-babel": "5.3.0",
|
||||||
"eslint-plugin-ban": "1.2.0",
|
"eslint-plugin-ban": "1.2.0",
|
||||||
"eslint-plugin-import": "2.18.0",
|
"eslint-plugin-import": "2.18.0",
|
||||||
|
@ -419,7 +419,7 @@
|
||||||
"pngjs": "^3.4.0",
|
"pngjs": "^3.4.0",
|
||||||
"postcss": "^7.0.5",
|
"postcss": "^7.0.5",
|
||||||
"postcss-url": "^8.0.0",
|
"postcss-url": "^8.0.0",
|
||||||
"prettier": "^1.14.3",
|
"prettier": "1.18.2",
|
||||||
"proxyquire": "1.8.0",
|
"proxyquire": "1.8.0",
|
||||||
"regenerate": "^1.4.0",
|
"regenerate": "^1.4.0",
|
||||||
"sass-lint": "^1.12.1",
|
"sass-lint": "^1.12.1",
|
||||||
|
|
2
packages/elastic-datemath/src/index.d.ts
vendored
2
packages/elastic-datemath/src/index.d.ts
vendored
|
@ -26,7 +26,7 @@ declare const datemath: {
|
||||||
weight: number;
|
weight: number;
|
||||||
type: 'calendar' | 'fixed' | 'mixed';
|
type: 'calendar' | 'fixed' | 'mixed';
|
||||||
base: number;
|
base: number;
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
units: Unit[];
|
units: Unit[];
|
||||||
unitsAsc: Unit[];
|
unitsAsc: Unit[];
|
||||||
|
|
|
@ -78,7 +78,7 @@ export function createProc(name, { cmd, args, cwd, env, stdin, log }) {
|
||||||
childProcess.stdin.end();
|
childProcess.stdin.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new class Proc {
|
return new (class Proc {
|
||||||
name = name;
|
name = name;
|
||||||
|
|
||||||
lines$ = Rx.merge(observeLines(childProcess.stdout), observeLines(childProcess.stderr)).pipe(
|
lines$ = Rx.merge(observeLines(childProcess.stdout), observeLines(childProcess.stderr)).pipe(
|
||||||
|
@ -156,5 +156,5 @@ export function createProc(name, { cmd, args, cwd, env, stdin, log }) {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}();
|
})();
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,9 +115,7 @@ export class Project {
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new CliError(
|
throw new CliError(
|
||||||
`[${this.name}] depends on [${
|
`[${this.name}] depends on [${project.name}] ${problemMsg}. Update its package.json to the expected value below.`,
|
||||||
project.name
|
|
||||||
}] ${problemMsg}. Update its package.json to the expected value below.`,
|
|
||||||
{
|
{
|
||||||
actual: `"${project.name}": "${versionInPackageJson}"`,
|
actual: `"${project.name}": "${versionInPackageJson}"`,
|
||||||
expected: `"${project.name}": "${expectedVersionInPackageJson}"`,
|
expected: `"${project.name}": "${expectedVersionInPackageJson}"`,
|
||||||
|
|
|
@ -54,7 +54,7 @@ export function createEsTestCluster(options = {}) {
|
||||||
|
|
||||||
const cluster = new Cluster(log);
|
const cluster = new Cluster(log);
|
||||||
|
|
||||||
return new class EsTestCluster {
|
return new (class EsTestCluster {
|
||||||
getStartTimeout() {
|
getStartTimeout() {
|
||||||
const second = 1000;
|
const second = 1000;
|
||||||
const minute = second * 60;
|
const minute = second * 60;
|
||||||
|
@ -121,7 +121,7 @@ export function createEsTestCluster(options = {}) {
|
||||||
|
|
||||||
return format(parts);
|
return format(parts);
|
||||||
}
|
}
|
||||||
}();
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -21,7 +21,7 @@ import url, { format as formatUrl } from 'url';
|
||||||
import pkg from '../../../../package.json';
|
import pkg from '../../../../package.json';
|
||||||
import { adminTestUser } from '../kbn';
|
import { adminTestUser } from '../kbn';
|
||||||
|
|
||||||
export const esTestConfig = new class EsTestConfig {
|
export const esTestConfig = new (class EsTestConfig {
|
||||||
getVersion() {
|
getVersion() {
|
||||||
return process.env.TEST_ES_BRANCH || pkg.version;
|
return process.env.TEST_ES_BRANCH || pkg.version;
|
||||||
}
|
}
|
||||||
|
@ -67,4 +67,4 @@ export const esTestConfig = new class EsTestConfig {
|
||||||
password: password,
|
password: password,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}();
|
})();
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
import { kibanaTestUser } from './users';
|
import { kibanaTestUser } from './users';
|
||||||
import url from 'url';
|
import url from 'url';
|
||||||
|
|
||||||
export const kbnTestConfig = new class KbnTestConfig {
|
export const kbnTestConfig = new (class KbnTestConfig {
|
||||||
getPort() {
|
getPort() {
|
||||||
return this.getUrlParts().port;
|
return this.getUrlParts().port;
|
||||||
}
|
}
|
||||||
|
@ -50,4 +50,4 @@ export const kbnTestConfig = new class KbnTestConfig {
|
||||||
password,
|
password,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}();
|
})();
|
||||||
|
|
2
packages/kbn-test/types/ftr.d.ts
vendored
2
packages/kbn-test/types/ftr.d.ts
vendored
|
@ -43,7 +43,7 @@ type MaybeAsyncInstance<T> = T extends Promise<infer X> ? AsyncInstance<X> & X :
|
||||||
type ProvidedTypeMap<T extends {}> = {
|
type ProvidedTypeMap<T extends {}> = {
|
||||||
[K in keyof T]: T[K] extends (...args: any[]) => any
|
[K in keyof T]: T[K] extends (...args: any[]) => any
|
||||||
? MaybeAsyncInstance<ReturnType<T[K]>>
|
? MaybeAsyncInstance<ReturnType<T[K]>>
|
||||||
: unknown
|
: unknown;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface GenericFtrProviderContext<
|
export interface GenericFtrProviderContext<
|
||||||
|
|
|
@ -66,7 +66,7 @@ export interface ChromeBreadcrumb {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type ChromeHelpExtension = (element: HTMLDivElement) => (() => void);
|
export type ChromeHelpExtension = (element: HTMLDivElement) => () => void;
|
||||||
|
|
||||||
interface ConstructorParams {
|
interface ConstructorParams {
|
||||||
browserSupportsCsp: boolean;
|
browserSupportsCsp: boolean;
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
extension?: (el: HTMLDivElement) => (() => void);
|
extension?: (el: HTMLDivElement) => () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class HeaderExtension extends React.Component<Props> {
|
export class HeaderExtension extends React.Component<Props> {
|
||||||
|
|
|
@ -379,12 +379,10 @@ describe('Notifications targetDomElement', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
let targetDomElementParentInStart: HTMLElement | null;
|
let targetDomElementParentInStart: HTMLElement | null;
|
||||||
MockNotificationsService.start.mockImplementation(
|
MockNotificationsService.start.mockImplementation(({ targetDomElement }): any => {
|
||||||
({ targetDomElement }): any => {
|
expect(targetDomElement.parentElement).not.toBeNull();
|
||||||
expect(targetDomElement.parentElement).not.toBeNull();
|
targetDomElementParentInStart = targetDomElement.parentElement;
|
||||||
targetDomElementParentInStart = targetDomElement.parentElement;
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Starting the core system should pass the targetDomElement as a child of the rootDomElement
|
// Starting the core system should pass the targetDomElement as a child of the rootDomElement
|
||||||
await core.setup();
|
await core.setup();
|
||||||
|
|
|
@ -19,31 +19,25 @@
|
||||||
|
|
||||||
import { deepFreeze } from '../../../../../utils/deep_freeze';
|
import { deepFreeze } from '../../../../../utils/deep_freeze';
|
||||||
|
|
||||||
deepFreeze(
|
deepFreeze({
|
||||||
{
|
foo: {
|
||||||
foo: {
|
bar: {
|
||||||
bar: {
|
baz: 1,
|
||||||
baz: 1,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
).foo.bar.baz = 2;
|
}).foo.bar.baz = 2;
|
||||||
|
|
||||||
deepFreeze(
|
deepFreeze({
|
||||||
{
|
foo: [
|
||||||
foo: [
|
{
|
||||||
{
|
bar: 1,
|
||||||
bar: 1,
|
},
|
||||||
},
|
],
|
||||||
],
|
}).foo[0].bar = 2;
|
||||||
}
|
|
||||||
).foo[0].bar = 2;
|
|
||||||
|
|
||||||
deepFreeze(
|
deepFreeze({
|
||||||
{
|
foo: [1],
|
||||||
foo: [1],
|
}).foo[0] = 2;
|
||||||
}
|
|
||||||
).foo[0] = 2;
|
|
||||||
|
|
||||||
deepFreeze({
|
deepFreeze({
|
||||||
foo: [1],
|
foo: [1],
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
import { EnvOptions } from '../env';
|
import { EnvOptions } from '../env';
|
||||||
|
|
||||||
type DeepPartial<T> = {
|
type DeepPartial<T> = {
|
||||||
[P in keyof T]?: T[P] extends Array<infer R> ? Array<DeepPartial<R>> : DeepPartial<T[P]>
|
[P in keyof T]?: T[P] extends Array<infer R> ? Array<DeepPartial<R>> : DeepPartial<T[P]>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function getEnvOptions(options: DeepPartial<EnvOptions> = {}): EnvOptions {
|
export function getEnvOptions(options: DeepPartial<EnvOptions> = {}): EnvOptions {
|
||||||
|
|
|
@ -132,9 +132,7 @@ export class Router {
|
||||||
// happen when it's used from JavaScript.
|
// happen when it's used from JavaScript.
|
||||||
if (route.validate === undefined) {
|
if (route.validate === undefined) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`The [${routeMethod}] at [${
|
`The [${routeMethod}] at [${route.path}] does not have a 'validate' specified. Use 'false' as the value if you want to bypass validation.`
|
||||||
route.path
|
|
||||||
}] does not have a 'validate' specified. Use 'false' as the value if you want to bypass validation.`
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,9 +58,7 @@ const LEVEL_COLORS = new Map([
|
||||||
/**
|
/**
|
||||||
* Default pattern used by PatternLayout if it's not overridden in the configuration.
|
* Default pattern used by PatternLayout if it's not overridden in the configuration.
|
||||||
*/
|
*/
|
||||||
const DEFAULT_PATTERN = `[${Parameters.Timestamp}][${Parameters.Level}][${Parameters.Context}] ${
|
const DEFAULT_PATTERN = `[${Parameters.Timestamp}][${Parameters.Level}][${Parameters.Context}] ${Parameters.Message}`;
|
||||||
Parameters.Message
|
|
||||||
}`;
|
|
||||||
|
|
||||||
const patternLayoutSchema = schema.object({
|
const patternLayoutSchema = schema.object({
|
||||||
highlight: schema.maybe(schema.boolean()),
|
highlight: schema.maybe(schema.boolean()),
|
||||||
|
|
|
@ -118,9 +118,7 @@ export async function parseManifest(pluginPath: string, packageInfo: PackageInfo
|
||||||
throw PluginDiscoveryError.invalidManifest(
|
throw PluginDiscoveryError.invalidManifest(
|
||||||
manifestPath,
|
manifestPath,
|
||||||
new Error(
|
new Error(
|
||||||
`The "configPath" in plugin manifest for "${
|
`The "configPath" in plugin manifest for "${manifest.id}" should either be a string or an array of strings.`
|
||||||
manifest.id
|
|
||||||
}" should either be a string or an array of strings.`
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -133,11 +131,7 @@ export async function parseManifest(pluginPath: string, packageInfo: PackageInfo
|
||||||
throw PluginDiscoveryError.incompatibleVersion(
|
throw PluginDiscoveryError.incompatibleVersion(
|
||||||
manifestPath,
|
manifestPath,
|
||||||
new Error(
|
new Error(
|
||||||
`Plugin "${
|
`Plugin "${manifest.id}" is only compatible with Kibana version "${expectedKibanaVersion}", but used Kibana version is "${packageInfo.version}".`
|
||||||
manifest.id
|
|
||||||
}" is only compatible with Kibana version "${expectedKibanaVersion}", but used Kibana version is "${
|
|
||||||
packageInfo.version
|
|
||||||
}".`
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -148,9 +142,7 @@ export async function parseManifest(pluginPath: string, packageInfo: PackageInfo
|
||||||
throw PluginDiscoveryError.invalidManifest(
|
throw PluginDiscoveryError.invalidManifest(
|
||||||
manifestPath,
|
manifestPath,
|
||||||
new Error(
|
new Error(
|
||||||
`Both "server" and "ui" are missing or set to "false" in plugin manifest for "${
|
`Both "server" and "ui" are missing or set to "false" in plugin manifest for "${manifest.id}", but at least one of these must be set to "true".`
|
||||||
manifest.id
|
|
||||||
}", but at least one of these must be set to "true".`
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -160,9 +152,7 @@ export async function parseManifest(pluginPath: string, packageInfo: PackageInfo
|
||||||
throw PluginDiscoveryError.invalidManifest(
|
throw PluginDiscoveryError.invalidManifest(
|
||||||
manifestPath,
|
manifestPath,
|
||||||
new Error(
|
new Error(
|
||||||
`Manifest for plugin "${
|
`Manifest for plugin "${manifest.id}" contains the following unrecognized properties: ${unknownManifestKeys}.`
|
||||||
manifest.id
|
|
||||||
}" contains the following unrecognized properties: ${unknownManifestKeys}.`
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,9 +48,7 @@ export function discover(config: PluginsConfig, coreContext: CoreContext) {
|
||||||
|
|
||||||
if (config.additionalPluginPaths.length) {
|
if (config.additionalPluginPaths.length) {
|
||||||
log.warn(
|
log.warn(
|
||||||
`Explicit plugin paths [${
|
`Explicit plugin paths [${config.additionalPluginPaths}] are only supported in development. Relative imports will not work in production.`
|
||||||
config.additionalPluginPaths
|
|
||||||
}] are only supported in development. Relative imports will not work in production.`
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ interface Server {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ElasticsearchPlugin {
|
interface ElasticsearchPlugin {
|
||||||
getCluster: ((name: 'admin') => { callWithInternalUser: CallCluster });
|
getCluster: (name: 'admin') => { callWithInternalUser: CallCluster };
|
||||||
waitUntilReady: () => Promise<any>;
|
waitUntilReady: () => Promise<any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,11 @@ export type SavedObjectsClientWrapperFactory<Request = unknown> = (
|
||||||
options: SavedObjectsClientWrapperOptions<Request>
|
options: SavedObjectsClientWrapperOptions<Request>
|
||||||
) => SavedObjectsClientContract;
|
) => SavedObjectsClientContract;
|
||||||
|
|
||||||
export type SavedObjectsClientFactory<Request = unknown> = (
|
export type SavedObjectsClientFactory<Request = unknown> = ({
|
||||||
{ request }: { request: Request }
|
request,
|
||||||
) => SavedObjectsClientContract;
|
}: {
|
||||||
|
request: Request;
|
||||||
|
}) => SavedObjectsClientContract;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provider for the Scoped Saved Object Client.
|
* Provider for the Scoped Saved Object Client.
|
||||||
|
|
|
@ -25,9 +25,11 @@ import { createFlagError, isFailError } from './fail';
|
||||||
import { Flags, getFlags, getHelp } from './flags';
|
import { Flags, getFlags, getHelp } from './flags';
|
||||||
|
|
||||||
type CleanupTask = () => void;
|
type CleanupTask = () => void;
|
||||||
type RunFn = (
|
type RunFn = (args: {
|
||||||
args: { log: ToolingLog; flags: Flags; addCleanupTask: (task: CleanupTask) => void }
|
log: ToolingLog;
|
||||||
) => Promise<void> | void;
|
flags: Flags;
|
||||||
|
addCleanupTask: (task: CleanupTask) => void;
|
||||||
|
}) => Promise<void> | void;
|
||||||
|
|
||||||
export interface Options {
|
export interface Options {
|
||||||
usage?: string;
|
usage?: string;
|
||||||
|
|
|
@ -64,7 +64,7 @@ export function createStats(name: string, log: ToolingLog) {
|
||||||
return indices[index];
|
return indices[index];
|
||||||
};
|
};
|
||||||
|
|
||||||
return new class Stats {
|
return new (class Stats {
|
||||||
/**
|
/**
|
||||||
* Record that an index was not restored because it already existed
|
* Record that an index was not restored because it already existed
|
||||||
* @param index
|
* @param index
|
||||||
|
@ -149,5 +149,5 @@ export function createStats(name: string, log: ToolingLog) {
|
||||||
fn(index, clone[index]);
|
fn(index, clone[index]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}();
|
})();
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,18 +48,15 @@ export const createRenderer = (run: ExpressionRunner): ExpressionRenderer => ({
|
||||||
}: ExpressionRendererProps) => {
|
}: ExpressionRendererProps) => {
|
||||||
const mountpoint: React.MutableRefObject<null | HTMLDivElement> = useRef(null);
|
const mountpoint: React.MutableRefObject<null | HTMLDivElement> = useRef(null);
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
if (mountpoint.current) {
|
||||||
if (mountpoint.current) {
|
run(expression, { ...options, element: mountpoint.current }).catch(result => {
|
||||||
run(expression, { ...options, element: mountpoint.current }).catch(result => {
|
if (onRenderFailure) {
|
||||||
if (onRenderFailure) {
|
onRenderFailure(result);
|
||||||
onRenderFailure(result);
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
}
|
}, [expression, mountpoint.current]);
|
||||||
},
|
|
||||||
[expression, mountpoint.current]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -84,17 +84,15 @@ export class FilterManager {
|
||||||
|
|
||||||
private handleStateUpdate(newFilters: Filter[]) {
|
private handleStateUpdate(newFilters: Filter[]) {
|
||||||
// global filters should always be first
|
// global filters should always be first
|
||||||
newFilters.sort(
|
newFilters.sort((a: Filter, b: Filter): number => {
|
||||||
(a: Filter, b: Filter): number => {
|
if (a.$state && a.$state.store === FilterStateStore.GLOBAL_STATE) {
|
||||||
if (a.$state && a.$state.store === FilterStateStore.GLOBAL_STATE) {
|
return -1;
|
||||||
return -1;
|
} else if (b.$state && b.$state.store === FilterStateStore.GLOBAL_STATE) {
|
||||||
} else if (b.$state && b.$state.store === FilterStateStore.GLOBAL_STATE) {
|
return 1;
|
||||||
return 1;
|
} else {
|
||||||
} else {
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
});
|
||||||
|
|
||||||
const filtersUpdated = !_.isEqual(this.filters, newFilters);
|
const filtersUpdated = !_.isEqual(this.filters, newFilters);
|
||||||
|
|
||||||
|
|
|
@ -85,9 +85,9 @@ export class ContactCardEmbeddableComponent extends React.Component<Props, State
|
||||||
<EuiFlexGroup justifyContent="flexEnd">
|
<EuiFlexGroup justifyContent="flexEnd">
|
||||||
<EuiFlexItem grow={false}>
|
<EuiFlexItem grow={false}>
|
||||||
<EuiFormRow label="">
|
<EuiFormRow label="">
|
||||||
<EuiButton onClick={this.emitContactTrigger}>{`Contact ${
|
<EuiButton
|
||||||
this.state.firstName
|
onClick={this.emitContactTrigger}
|
||||||
}`}</EuiButton>
|
>{`Contact ${this.state.firstName}`}</EuiButton>
|
||||||
</EuiFormRow>
|
</EuiFormRow>
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
</EuiFlexGroup>
|
</EuiFlexGroup>
|
||||||
|
|
|
@ -87,9 +87,13 @@ export interface DashboardAppScope extends ng.IScope {
|
||||||
getShouldShowEditHelp: () => boolean;
|
getShouldShowEditHelp: () => boolean;
|
||||||
getShouldShowViewHelp: () => boolean;
|
getShouldShowViewHelp: () => boolean;
|
||||||
updateQueryAndFetch: ({ query, dateRange }: { query: Query; dateRange?: TimeRange }) => void;
|
updateQueryAndFetch: ({ query, dateRange }: { query: Query; dateRange?: TimeRange }) => void;
|
||||||
onRefreshChange: (
|
onRefreshChange: ({
|
||||||
{ isPaused, refreshInterval }: { isPaused: boolean; refreshInterval: any }
|
isPaused,
|
||||||
) => void;
|
refreshInterval,
|
||||||
|
}: {
|
||||||
|
isPaused: boolean;
|
||||||
|
refreshInterval: any;
|
||||||
|
}) => void;
|
||||||
onFiltersUpdated: (filters: Filter[]) => void;
|
onFiltersUpdated: (filters: Filter[]) => void;
|
||||||
$listenAndDigestAsync: any;
|
$listenAndDigestAsync: any;
|
||||||
onCancelApplyFilters: () => void;
|
onCancelApplyFilters: () => void;
|
||||||
|
|
|
@ -33,16 +33,14 @@ interface SaveOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onSave: (
|
onSave: ({
|
||||||
{
|
newTitle,
|
||||||
newTitle,
|
newDescription,
|
||||||
newDescription,
|
newCopyOnSave,
|
||||||
newCopyOnSave,
|
newTimeRestore,
|
||||||
newTimeRestore,
|
isTitleDuplicateConfirmed,
|
||||||
isTitleDuplicateConfirmed,
|
onTitleDuplicate,
|
||||||
onTitleDuplicate,
|
}: SaveOptions) => void;
|
||||||
}: SaveOptions
|
|
||||||
) => void;
|
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
title: string;
|
title: string;
|
||||||
description: string;
|
description: string;
|
||||||
|
|
|
@ -59,9 +59,7 @@ export class VisualizeEmbeddableFactory extends EmbeddableFactory<VisualizationA
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
getTooltipForSavedObject: savedObject => {
|
getTooltipForSavedObject: savedObject => {
|
||||||
return `${savedObject.attributes.title} (${
|
return `${savedObject.attributes.title} (${visTypes.byName[JSON.parse(savedObject.attributes.visState).type].title})`;
|
||||||
visTypes.byName[JSON.parse(savedObject.attributes.visState).type].title
|
|
||||||
})`;
|
|
||||||
},
|
},
|
||||||
showSavedObject: savedObject => {
|
showSavedObject: savedObject => {
|
||||||
const typeName: string = JSON.parse(savedObject.attributes.visState).type;
|
const typeName: string = JSON.parse(savedObject.attributes.visState).type;
|
||||||
|
|
6
src/legacy/server/index_patterns/mixin.d.ts
vendored
6
src/legacy/server/index_patterns/mixin.d.ts
vendored
|
@ -19,6 +19,6 @@
|
||||||
|
|
||||||
import { IndexPatternsService } from './service';
|
import { IndexPatternsService } from './service';
|
||||||
|
|
||||||
export type IndexPatternsServiceFactory = (
|
export type IndexPatternsServiceFactory = (args: {
|
||||||
args: { callCluster: (endpoint: string, clientParams: any, options: any) => Promise<any> }
|
callCluster: (endpoint: string, clientParams: any, options: any) => Promise<any>;
|
||||||
) => IndexPatternsService;
|
}) => IndexPatternsService;
|
||||||
|
|
|
@ -172,19 +172,13 @@ function InputList({ config, list, onChange, setValidity }: InputListProps) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// responsible for discarding changes
|
// responsible for discarding changes
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
setModels(getUpdatedModels(list, models));
|
||||||
setModels(getUpdatedModels(list, models));
|
}, [list]);
|
||||||
},
|
|
||||||
[list]
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
setValidity(!hasInvalidValues(models));
|
||||||
setValidity(!hasInvalidValues(models));
|
}, [models]);
|
||||||
},
|
|
||||||
[models]
|
|
||||||
);
|
|
||||||
|
|
||||||
// resposible for setting up an initial value when there is no default value
|
// resposible for setting up an initial value when there is no default value
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
@ -76,25 +76,19 @@ function DateRangesParamEditor({
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
// responsible for discarding changes
|
||||||
// responsible for discarding changes
|
if (
|
||||||
if (
|
value.length !== ranges.length ||
|
||||||
value.length !== ranges.length ||
|
value.some((range, index) => !isEqual(range, omit(ranges[index], 'id')))
|
||||||
value.some((range, index) => !isEqual(range, omit(ranges[index], 'id')))
|
) {
|
||||||
) {
|
setRanges(value.map(range => ({ ...range, id: generateId() })));
|
||||||
setRanges(value.map(range => ({ ...range, id: generateId() })));
|
}
|
||||||
}
|
}, [value]);
|
||||||
},
|
|
||||||
[value]
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
setValidity(!hasInvalidRange);
|
||||||
setValidity(!hasInvalidRange);
|
}, [hasInvalidRange]);
|
||||||
},
|
|
||||||
[hasInvalidRange]
|
|
||||||
);
|
|
||||||
|
|
||||||
const updateRanges = (rangeValues: DateRangeValuesModel[]) => {
|
const updateRanges = (rangeValues: DateRangeValuesModel[]) => {
|
||||||
// do not set internal id parameter into saved object
|
// do not set internal id parameter into saved object
|
||||||
|
|
|
@ -61,14 +61,11 @@ function ExtendedBoundsParamEditor({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
setValidity(isValid);
|
||||||
setValidity(isValid);
|
|
||||||
|
|
||||||
return () => setValidity(true);
|
return () => setValidity(true);
|
||||||
},
|
}, [isValid]);
|
||||||
[isValid]
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleChange = (ev: ChangeEvent<HTMLInputElement>, name: string) => {
|
const handleChange = (ev: ChangeEvent<HTMLInputElement>, name: string) => {
|
||||||
setValue({
|
setValue({
|
||||||
|
|
|
@ -78,16 +78,13 @@ function FieldParamEditor({
|
||||||
|
|
||||||
const isValid = !!value && !errors.length;
|
const isValid = !!value && !errors.length;
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
setValidity(isValid);
|
||||||
setValidity(isValid);
|
|
||||||
|
|
||||||
if (!!errors.length) {
|
if (!!errors.length) {
|
||||||
setTouched();
|
setTouched();
|
||||||
}
|
}
|
||||||
},
|
}, [isValid]);
|
||||||
[isValid]
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// set field if only one available
|
// set field if only one available
|
||||||
|
|
|
@ -45,18 +45,15 @@ function FiltersParamEditor({ agg, value, setValue }: AggParamEditorProps<Filter
|
||||||
setValue(filters.map(filter => omit({ ...filter, input: filter.input }, 'id')));
|
setValue(filters.map(filter => omit({ ...filter, input: filter.input }, 'id')));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
// responsible for discarding changes
|
||||||
// responsible for discarding changes
|
if (
|
||||||
if (
|
value.length !== filters.length ||
|
||||||
value.length !== filters.length ||
|
value.some((filter, index) => !isEqual(filter, omit(filters[index], 'id')))
|
||||||
value.some((filter, index) => !isEqual(filter, omit(filters[index], 'id')))
|
) {
|
||||||
) {
|
setFilters(value.map(filter => ({ ...filter, id: generateId() })));
|
||||||
setFilters(value.map(filter => ({ ...filter, id: generateId() })));
|
}
|
||||||
}
|
}, [value]);
|
||||||
},
|
|
||||||
[value]
|
|
||||||
);
|
|
||||||
|
|
||||||
const updateFilters = (updatedFilters: FilterValue[]) => {
|
const updateFilters = (updatedFilters: FilterValue[]) => {
|
||||||
// do not set internal id parameter into saved object
|
// do not set internal id parameter into saved object
|
||||||
|
|
|
@ -24,12 +24,9 @@ import { SwitchParamEditor } from './switch';
|
||||||
import { isType } from '../buckets/migrate_include_exclude_format';
|
import { isType } from '../buckets/migrate_include_exclude_format';
|
||||||
|
|
||||||
function HasExtendedBoundsParamEditor(props: AggParamEditorProps<boolean>) {
|
function HasExtendedBoundsParamEditor(props: AggParamEditorProps<boolean>) {
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
props.setValue(props.value && props.agg.params.min_doc_count);
|
||||||
props.setValue(props.value && props.agg.params.min_doc_count);
|
}, [props.agg.params.min_doc_count]);
|
||||||
},
|
|
||||||
[props.agg.params.min_doc_count]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SwitchParamEditor
|
<SwitchParamEditor
|
||||||
|
|
|
@ -45,77 +45,68 @@ function MetricAggParamEditor({
|
||||||
});
|
});
|
||||||
const isValid = !!value;
|
const isValid = !!value;
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
setValidity(isValid);
|
||||||
setValidity(isValid);
|
}, [isValid]);
|
||||||
},
|
|
||||||
[isValid]
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
if (responseValueAggs && value && value !== 'custom') {
|
||||||
if (responseValueAggs && value && value !== 'custom') {
|
// ensure that metricAgg is set to a valid agg
|
||||||
// ensure that metricAgg is set to a valid agg
|
const respAgg = responseValueAggs
|
||||||
const respAgg = responseValueAggs
|
.filter(isCompatibleAgg)
|
||||||
.filter(isCompatibleAgg)
|
.find(aggregation => aggregation.id === value);
|
||||||
.find(aggregation => aggregation.id === value);
|
|
||||||
|
|
||||||
if (!respAgg) {
|
if (!respAgg) {
|
||||||
setValue();
|
setValue();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
[responseValueAggs]
|
}, [responseValueAggs]);
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
// check buckets
|
||||||
// check buckets
|
const lastBucket: AggConfig = findLast(
|
||||||
const lastBucket: AggConfig = findLast(
|
state.aggs,
|
||||||
state.aggs,
|
aggr => aggr.type && aggr.type.type === 'buckets'
|
||||||
aggr => aggr.type && aggr.type.type === 'buckets'
|
);
|
||||||
|
const bucketHasType = lastBucket && lastBucket.type;
|
||||||
|
const bucketIsHistogram =
|
||||||
|
bucketHasType && ['date_histogram', 'histogram'].includes(lastBucket.type.name);
|
||||||
|
const canUseAggregation = lastBucket && bucketIsHistogram;
|
||||||
|
|
||||||
|
// remove errors on all buckets
|
||||||
|
state.aggs.forEach((aggr: AggConfig) => {
|
||||||
|
if (aggr.error) {
|
||||||
|
subAggParams.onAggErrorChanged(aggr);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (canUseAggregation) {
|
||||||
|
subAggParams.onAggParamsChange(
|
||||||
|
lastBucket.params,
|
||||||
|
'min_doc_count',
|
||||||
|
lastBucket.type.name === 'histogram' ? 1 : 0
|
||||||
);
|
);
|
||||||
const bucketHasType = lastBucket && lastBucket.type;
|
} else {
|
||||||
const bucketIsHistogram =
|
if (lastBucket) {
|
||||||
bucketHasType && ['date_histogram', 'histogram'].includes(lastBucket.type.name);
|
subAggParams.onAggErrorChanged(
|
||||||
const canUseAggregation = lastBucket && bucketIsHistogram;
|
lastBucket,
|
||||||
|
i18n.translate('common.ui.aggTypes.metrics.wrongLastBucketTypeErrorMessage', {
|
||||||
// remove errors on all buckets
|
defaultMessage:
|
||||||
state.aggs.forEach((aggr: AggConfig) => {
|
'Last bucket aggregation must be "Date Histogram" or "Histogram" when using "{type}" metric aggregation.',
|
||||||
if (aggr.error) {
|
values: { type: agg.type.title },
|
||||||
subAggParams.onAggErrorChanged(aggr);
|
description: 'Date Histogram and Histogram should not be translated',
|
||||||
}
|
})
|
||||||
});
|
|
||||||
|
|
||||||
if (canUseAggregation) {
|
|
||||||
subAggParams.onAggParamsChange(
|
|
||||||
lastBucket.params,
|
|
||||||
'min_doc_count',
|
|
||||||
lastBucket.type.name === 'histogram' ? 1 : 0
|
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
if (lastBucket) {
|
|
||||||
subAggParams.onAggErrorChanged(
|
|
||||||
lastBucket,
|
|
||||||
i18n.translate('common.ui.aggTypes.metrics.wrongLastBucketTypeErrorMessage', {
|
|
||||||
defaultMessage:
|
|
||||||
'Last bucket aggregation must be "Date Histogram" or "Histogram" when using "{type}" metric aggregation.',
|
|
||||||
values: { type: agg.type.title },
|
|
||||||
description: 'Date Histogram and Histogram should not be translated',
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
// clear errors in last bucket before component destroyed
|
// clear errors in last bucket before component destroyed
|
||||||
if (lastBucket && lastBucket.error) {
|
if (lastBucket && lastBucket.error) {
|
||||||
subAggParams.onAggErrorChanged(lastBucket);
|
subAggParams.onAggErrorChanged(lastBucket);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
}, [value, responseValueAggs]);
|
||||||
[value, responseValueAggs]
|
|
||||||
);
|
|
||||||
|
|
||||||
const options = responseValueAggs
|
const options = responseValueAggs
|
||||||
? responseValueAggs
|
? responseValueAggs
|
||||||
|
|
|
@ -26,14 +26,11 @@ import { isStringType } from '../buckets/migrate_include_exclude_format';
|
||||||
function MissingBucketParamEditor(props: AggParamEditorProps<boolean>) {
|
function MissingBucketParamEditor(props: AggParamEditorProps<boolean>) {
|
||||||
const fieldTypeIsNotString = !isStringType(props.agg);
|
const fieldTypeIsNotString = !isStringType(props.agg);
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
if (fieldTypeIsNotString) {
|
||||||
if (fieldTypeIsNotString) {
|
props.setValue(false);
|
||||||
props.setValue(false);
|
}
|
||||||
}
|
}, [fieldTypeIsNotString]);
|
||||||
},
|
|
||||||
[fieldTypeIsNotString]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SwitchParamEditor
|
<SwitchParamEditor
|
||||||
|
|
|
@ -58,12 +58,9 @@ function NumberIntervalParamEditor({
|
||||||
const min = base || 0;
|
const min = base || 0;
|
||||||
const isValid = value !== undefined && value >= min;
|
const isValid = value !== undefined && value >= min;
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
setValidity(isValid);
|
||||||
setValidity(isValid);
|
}, [isValid]);
|
||||||
},
|
|
||||||
[isValid]
|
|
||||||
);
|
|
||||||
|
|
||||||
const onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
const onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const numberValue = parseFloat(event.target.value);
|
const numberValue = parseFloat(event.target.value);
|
||||||
|
|
|
@ -37,12 +37,9 @@ function OrderParamEditor({
|
||||||
});
|
});
|
||||||
const isValid = !!value;
|
const isValid = !!value;
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
setValidity(isValid);
|
||||||
setValidity(isValid);
|
}, [isValid]);
|
||||||
},
|
|
||||||
[isValid]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EuiFormRow
|
<EuiFormRow
|
||||||
|
|
|
@ -31,22 +31,19 @@ function OrderAggParamEditor({
|
||||||
setTouched,
|
setTouched,
|
||||||
subAggParams,
|
subAggParams,
|
||||||
}: AggParamEditorProps<AggConfig>) {
|
}: AggParamEditorProps<AggConfig>) {
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
if (responseValueAggs) {
|
||||||
if (responseValueAggs) {
|
const orderBy = agg.params.orderBy;
|
||||||
const orderBy = agg.params.orderBy;
|
|
||||||
|
|
||||||
// we aren't creating a custom aggConfig
|
// we aren't creating a custom aggConfig
|
||||||
if (!orderBy || orderBy !== 'custom') {
|
if (!orderBy || orderBy !== 'custom') {
|
||||||
setValue(null);
|
setValue(null);
|
||||||
} else {
|
} else {
|
||||||
const paramDef = agg.type.params.byName.orderAgg;
|
const paramDef = agg.type.params.byName.orderAgg;
|
||||||
setValue(value || paramDef.makeOrderAgg(agg));
|
setValue(value || paramDef.makeOrderAgg(agg));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
[agg.params.orderBy, responseValueAggs]
|
}, [agg.params.orderBy, responseValueAggs]);
|
||||||
);
|
|
||||||
|
|
||||||
const [innerState, setInnerState] = useState(true);
|
const [innerState, setInnerState] = useState(true);
|
||||||
|
|
||||||
|
|
|
@ -53,12 +53,9 @@ function OrderByParamEditor({
|
||||||
});
|
});
|
||||||
const isValid = !!value;
|
const isValid = !!value;
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
setValidity(isValid);
|
||||||
setValidity(isValid);
|
}, [isValid]);
|
||||||
},
|
|
||||||
[isValid]
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// setup the initial value of orderBy
|
// setup the initial value of orderBy
|
||||||
|
@ -73,21 +70,18 @@ function OrderByParamEditor({
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
if (responseValueAggs && value && value !== 'custom') {
|
||||||
if (responseValueAggs && value && value !== 'custom') {
|
// ensure that orderBy is set to a valid agg
|
||||||
// ensure that orderBy is set to a valid agg
|
const respAgg = responseValueAggs
|
||||||
const respAgg = responseValueAggs
|
.filter(isCompatibleAgg)
|
||||||
.filter(isCompatibleAgg)
|
.find(aggregation => aggregation.id === value);
|
||||||
.find(aggregation => aggregation.id === value);
|
|
||||||
|
|
||||||
if (!respAgg) {
|
if (!respAgg) {
|
||||||
setValue('_key');
|
setValue('_key');
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
[responseValueAggs]
|
}, [responseValueAggs]);
|
||||||
);
|
|
||||||
|
|
||||||
const defaultOptions = [
|
const defaultOptions = [
|
||||||
{
|
{
|
||||||
|
|
|
@ -58,18 +58,15 @@ function RangesParamEditor({ agg, value = [], setValue }: AggParamEditorProps<Ra
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
// responsible for discarding changes
|
||||||
// responsible for discarding changes
|
if (
|
||||||
if (
|
value.length !== ranges.length ||
|
||||||
value.length !== ranges.length ||
|
value.some((range, index) => !isEqual(range, omit(ranges[index], 'id')))
|
||||||
value.some((range, index) => !isEqual(range, omit(ranges[index], 'id')))
|
) {
|
||||||
) {
|
setRanges(value.map(range => ({ ...range, id: generateId() })));
|
||||||
setRanges(value.map(range => ({ ...range, id: generateId() })));
|
}
|
||||||
}
|
}, [value]);
|
||||||
},
|
|
||||||
[value]
|
|
||||||
);
|
|
||||||
|
|
||||||
const updateRanges = (rangeValues: RangeValuesModel[]) => {
|
const updateRanges = (rangeValues: RangeValuesModel[]) => {
|
||||||
// do not set internal id parameter into saved object
|
// do not set internal id parameter into saved object
|
||||||
|
|
|
@ -54,12 +54,9 @@ function RawJsonParamEditor({
|
||||||
setValidity(isValidJson(textValue));
|
setValidity(isValidJson(textValue));
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
setValidity(isValid);
|
||||||
setValidity(isValid);
|
}, [isValid]);
|
||||||
},
|
|
||||||
[isValid]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EuiFormRow
|
<EuiFormRow
|
||||||
|
|
|
@ -46,12 +46,9 @@ function SizeParamEditor({
|
||||||
);
|
);
|
||||||
const isValid = disabled || Number(value) > 0;
|
const isValid = disabled || Number(value) > 0;
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
setValidity(isValid);
|
||||||
setValidity(isValid);
|
}, [isValid]);
|
||||||
},
|
|
||||||
[isValid]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EuiFormRow
|
<EuiFormRow
|
||||||
|
|
|
@ -33,12 +33,9 @@ function StringParamEditor({
|
||||||
}: AggParamEditorProps<string>) {
|
}: AggParamEditorProps<string>) {
|
||||||
const isValid = aggParam.required ? !!value : true;
|
const isValid = aggParam.required ? !!value : true;
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
setValidity(isValid);
|
||||||
setValidity(isValid);
|
}, [isValid]);
|
||||||
},
|
|
||||||
[isValid]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EuiFormRow
|
<EuiFormRow
|
||||||
|
|
|
@ -31,17 +31,14 @@ function SubAggParamEditor({
|
||||||
setTouched,
|
setTouched,
|
||||||
subAggParams,
|
subAggParams,
|
||||||
}: AggParamEditorProps<AggConfig>) {
|
}: AggParamEditorProps<AggConfig>) {
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
// we aren't creating a custom aggConfig
|
||||||
// we aren't creating a custom aggConfig
|
if (agg.params.metricAgg !== 'custom') {
|
||||||
if (agg.params.metricAgg !== 'custom') {
|
setValue(null);
|
||||||
setValue(null);
|
} else if (!agg.params.customMetric) {
|
||||||
} else if (!agg.params.customMetric) {
|
setValue(agg.type.params.byName.customMetric.makeAgg(agg));
|
||||||
setValue(agg.type.params.byName.customMetric.makeAgg(agg));
|
}
|
||||||
}
|
}, [value, responseValueAggs]);
|
||||||
},
|
|
||||||
[value, responseValueAggs]
|
|
||||||
);
|
|
||||||
|
|
||||||
const [innerState, setInnerState] = useState(true);
|
const [innerState, setInnerState] = useState(true);
|
||||||
|
|
||||||
|
|
|
@ -115,12 +115,9 @@ function TimeIntervalParamEditor({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
setValidity(isValid);
|
||||||
setValidity(isValid);
|
}, [isValid]);
|
||||||
},
|
|
||||||
[isValid]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EuiFormRow
|
<EuiFormRow
|
||||||
|
|
|
@ -72,34 +72,28 @@ function TopAggregateParamEditor({
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
setValidity(isValid);
|
||||||
setValidity(isValid);
|
}, [isValid]);
|
||||||
},
|
|
||||||
[isValid]
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
if (isFirstRun.current) {
|
||||||
if (isFirstRun.current) {
|
isFirstRun.current = false;
|
||||||
isFirstRun.current = false;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
if (aggParam.options.byValue[value.value]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value) {
|
setValue();
|
||||||
if (aggParam.options.byValue[value.value]) {
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setValue();
|
if (filteredOptions.length === 1) {
|
||||||
}
|
setValue(aggParam.options.byValue[filteredOptions[0].value]);
|
||||||
|
}
|
||||||
if (filteredOptions.length === 1) {
|
}, [fieldType]);
|
||||||
setValue(aggParam.options.byValue[filteredOptions[0].value]);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[fieldType]
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
const handleChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
if (event.target.value === emptyValue.value) {
|
if (event.target.value === emptyValue.value) {
|
||||||
|
|
|
@ -67,30 +67,24 @@ function NumberList({
|
||||||
const [ascendingError, setAscendingError] = useState(EMPTY_STRING);
|
const [ascendingError, setAscendingError] = useState(EMPTY_STRING);
|
||||||
|
|
||||||
// responsible for discarding changes
|
// responsible for discarding changes
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
const updatedModels = getUpdatedModels(numberArray, models, numberRange);
|
||||||
const updatedModels = getUpdatedModels(numberArray, models, numberRange);
|
if (validateAscendingOrder) {
|
||||||
if (validateAscendingOrder) {
|
const isOrderValid = validateOrder(updatedModels);
|
||||||
const isOrderValid = validateOrder(updatedModels);
|
setAscendingError(
|
||||||
setAscendingError(
|
isOrderValid
|
||||||
isOrderValid
|
? i18n.translate('common.ui.aggTypes.numberList.invalidAscOrderErrorMessage', {
|
||||||
? i18n.translate('common.ui.aggTypes.numberList.invalidAscOrderErrorMessage', {
|
defaultMessage: 'The values should be in ascending order.',
|
||||||
defaultMessage: 'The values should be in ascending order.',
|
})
|
||||||
})
|
: EMPTY_STRING
|
||||||
: EMPTY_STRING
|
);
|
||||||
);
|
}
|
||||||
}
|
setModels(updatedModels);
|
||||||
setModels(updatedModels);
|
}, [numberArray]);
|
||||||
},
|
|
||||||
[numberArray]
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
setValidity(!hasInvalidValues(models));
|
||||||
setValidity(!hasInvalidValues(models));
|
}, [models]);
|
||||||
},
|
|
||||||
[models]
|
|
||||||
);
|
|
||||||
|
|
||||||
// resposible for setting up an initial value ([0]) when there is no default value
|
// resposible for setting up an initial value ([0]) when there is no default value
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
@ -22,23 +22,19 @@
|
||||||
*/
|
*/
|
||||||
import { StaticIndexPattern } from 'ui/index_patterns';
|
import { StaticIndexPattern } from 'ui/index_patterns';
|
||||||
|
|
||||||
export type AutocompleteProvider = (
|
export type AutocompleteProvider = (args: {
|
||||||
args: {
|
config: {
|
||||||
config: {
|
get(configKey: string): any;
|
||||||
get(configKey: string): any;
|
};
|
||||||
};
|
indexPatterns: StaticIndexPattern[];
|
||||||
indexPatterns: StaticIndexPattern[];
|
boolFilter?: any;
|
||||||
boolFilter?: any;
|
}) => GetSuggestions;
|
||||||
}
|
|
||||||
) => GetSuggestions;
|
|
||||||
|
|
||||||
export type GetSuggestions = (
|
export type GetSuggestions = (args: {
|
||||||
args: {
|
query: string;
|
||||||
query: string;
|
selectionStart: number;
|
||||||
selectionStart: number;
|
selectionEnd: number;
|
||||||
selectionEnd: number;
|
}) => Promise<AutocompleteSuggestion[]>;
|
||||||
}
|
|
||||||
) => Promise<AutocompleteSuggestion[]>;
|
|
||||||
|
|
||||||
export type AutocompleteSuggestionType =
|
export type AutocompleteSuggestionType =
|
||||||
| 'field'
|
| 'field'
|
||||||
|
|
|
@ -33,7 +33,7 @@ export interface NavControl {
|
||||||
name: string;
|
name: string;
|
||||||
order: number;
|
order: number;
|
||||||
side: NavControlSide;
|
side: NavControlSide;
|
||||||
render: (targetDomElement: HTMLDivElement) => (() => void);
|
render: (targetDomElement: HTMLDivElement) => () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ChromeHeaderNavControlsRegistry = UIRegistry<NavControl> &
|
export type ChromeHeaderNavControlsRegistry = UIRegistry<NavControl> &
|
||||||
|
|
|
@ -30,14 +30,11 @@ interface DefaultEditorAggParamProps<T> extends AggParamCommonProps<T> {
|
||||||
function DefaultEditorAggParam<T>(props: DefaultEditorAggParamProps<T>) {
|
function DefaultEditorAggParam<T>(props: DefaultEditorAggParamProps<T>) {
|
||||||
const { agg, aggParam, paramEditor: ParamEditor, onChange, setValidity, ...rest } = props;
|
const { agg, aggParam, paramEditor: ParamEditor, onChange, setValidity, ...rest } = props;
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
if (aggParam.shouldShow && !aggParam.shouldShow(agg)) {
|
||||||
if (aggParam.shouldShow && !aggParam.shouldShow(agg)) {
|
setValidity(true);
|
||||||
setValidity(true);
|
}
|
||||||
}
|
}, [agg, agg.params.field]);
|
||||||
},
|
|
||||||
[agg, agg.params.field]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (aggParam.shouldShow && !aggParam.shouldShow(agg)) {
|
if (aggParam.shouldShow && !aggParam.shouldShow(agg)) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -115,60 +115,48 @@ function DefaultEditorAggParams({
|
||||||
// reset validity before component destroyed
|
// reset validity before component destroyed
|
||||||
useUnmount(() => setValidity(true));
|
useUnmount(() => setValidity(true));
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
Object.entries(editorConfig).forEach(([param, paramConfig]) => {
|
||||||
Object.entries(editorConfig).forEach(([param, paramConfig]) => {
|
const paramOptions = agg.type.params.find(
|
||||||
const paramOptions = agg.type.params.find(
|
(paramOption: AggParam) => paramOption.name === param
|
||||||
(paramOption: AggParam) => paramOption.name === param
|
);
|
||||||
);
|
|
||||||
|
|
||||||
const hasFixedValue = paramConfig.hasOwnProperty(FIXED_VALUE_PROP);
|
const hasFixedValue = paramConfig.hasOwnProperty(FIXED_VALUE_PROP);
|
||||||
const hasDefault = paramConfig.hasOwnProperty(DEFAULT_PROP);
|
const hasDefault = paramConfig.hasOwnProperty(DEFAULT_PROP);
|
||||||
// If the parameter has a fixed value in the config, set this value.
|
// If the parameter has a fixed value in the config, set this value.
|
||||||
// Also for all supported configs we should freeze the editor for this param.
|
// Also for all supported configs we should freeze the editor for this param.
|
||||||
if (hasFixedValue || hasDefault) {
|
if (hasFixedValue || hasDefault) {
|
||||||
let newValue;
|
let newValue;
|
||||||
let property = FIXED_VALUE_PROP;
|
let property = FIXED_VALUE_PROP;
|
||||||
let typedParamConfig: EditorParamConfigType = paramConfig as FixedParam;
|
let typedParamConfig: EditorParamConfigType = paramConfig as FixedParam;
|
||||||
|
|
||||||
if (hasDefault) {
|
if (hasDefault) {
|
||||||
property = DEFAULT_PROP;
|
property = DEFAULT_PROP;
|
||||||
typedParamConfig = paramConfig as TimeIntervalParam;
|
typedParamConfig = paramConfig as TimeIntervalParam;
|
||||||
}
|
|
||||||
|
|
||||||
if (paramOptions && paramOptions.deserialize) {
|
|
||||||
newValue = paramOptions.deserialize(typedParamConfig[property]);
|
|
||||||
} else {
|
|
||||||
newValue = typedParamConfig[property];
|
|
||||||
}
|
|
||||||
onAggParamsChange(agg.params, param, newValue);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
},
|
|
||||||
[agg.type]
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(
|
if (paramOptions && paramOptions.deserialize) {
|
||||||
() => {
|
newValue = paramOptions.deserialize(typedParamConfig[property]);
|
||||||
setTouched(false);
|
} else {
|
||||||
},
|
newValue = typedParamConfig[property];
|
||||||
[agg.type]
|
}
|
||||||
);
|
onAggParamsChange(agg.params, param, newValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, [agg.type]);
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
setTouched(false);
|
||||||
setValidity(isFormValid);
|
}, [agg.type]);
|
||||||
},
|
|
||||||
[isFormValid, agg.type]
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
setValidity(isFormValid);
|
||||||
// when all invalid controls were touched or they are untouched
|
}, [isFormValid, agg.type]);
|
||||||
setTouched(isAllInvalidParamsTouched);
|
|
||||||
},
|
useEffect(() => {
|
||||||
[isAllInvalidParamsTouched]
|
// when all invalid controls were touched or they are untouched
|
||||||
);
|
setTouched(isAllInvalidParamsTouched);
|
||||||
|
}, [isAllInvalidParamsTouched]);
|
||||||
|
|
||||||
const renderParam = (paramInstance: ParamInstance, model: AggParamsItem) => {
|
const renderParam = (paramInstance: ParamInstance, model: AggParamsItem) => {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -102,21 +102,15 @@ function DefaultEditorAggSelect({
|
||||||
|
|
||||||
const isValid = !!value && !errors.length;
|
const isValid = !!value && !errors.length;
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
setValidity(isValid);
|
||||||
setValidity(isValid);
|
}, [isValid]);
|
||||||
},
|
|
||||||
[isValid]
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
if (errors.length) {
|
||||||
if (errors.length) {
|
setTouched();
|
||||||
setTouched();
|
}
|
||||||
}
|
}, [errors.length]);
|
||||||
},
|
|
||||||
[errors.length]
|
|
||||||
);
|
|
||||||
|
|
||||||
const onChange = (options: EuiComboBoxOptionProps[]) => {
|
const onChange = (options: EuiComboBoxOptionProps[]) => {
|
||||||
const selectedOption = get(options, '0.value');
|
const selectedOption = get(options, '0.value');
|
||||||
|
|
|
@ -25,13 +25,10 @@ export function useObservable<T>(observable$: Observable<T>, initialValue: T): T
|
||||||
export function useObservable<T>(observable$: Observable<T>, initialValue?: T): T | undefined {
|
export function useObservable<T>(observable$: Observable<T>, initialValue?: T): T | undefined {
|
||||||
const [value, update] = useState<T | undefined>(initialValue);
|
const [value, update] = useState<T | undefined>(initialValue);
|
||||||
|
|
||||||
useLayoutEffect(
|
useLayoutEffect(() => {
|
||||||
() => {
|
const s = observable$.subscribe(update);
|
||||||
const s = observable$.subscribe(update);
|
return () => s.unsubscribe();
|
||||||
return () => s.unsubscribe();
|
}, [observable$]);
|
||||||
},
|
|
||||||
[observable$]
|
|
||||||
);
|
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ export function RetryProvider({ getService }: FtrProviderContext) {
|
||||||
const config = getService('config');
|
const config = getService('config');
|
||||||
const log = getService('log');
|
const log = getService('log');
|
||||||
|
|
||||||
return new class Retry {
|
return new (class Retry {
|
||||||
public async tryForTime<T>(
|
public async tryForTime<T>(
|
||||||
timeout: number,
|
timeout: number,
|
||||||
block: () => Promise<T>,
|
block: () => Promise<T>,
|
||||||
|
@ -76,5 +76,5 @@ export function RetryProvider({ getService }: FtrProviderContext) {
|
||||||
onFailureBlock,
|
onFailureBlock,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}();
|
})();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ export function AppsMenuProvider({ getService }: FtrProviderContext) {
|
||||||
const testSubjects = getService('testSubjects');
|
const testSubjects = getService('testSubjects');
|
||||||
const log = getService('log');
|
const log = getService('log');
|
||||||
|
|
||||||
return new class AppsMenu {
|
return new (class AppsMenu {
|
||||||
/**
|
/**
|
||||||
* Get the text and href from each of the links in the apps menu
|
* Get the text and href from each of the links in the apps menu
|
||||||
*/
|
*/
|
||||||
|
@ -69,5 +69,5 @@ export function AppsMenuProvider({ getService }: FtrProviderContext) {
|
||||||
// Intentionally empty
|
// Intentionally empty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}();
|
})();
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ export async function BrowserProvider({ getService }: FtrProviderContext) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return new class BrowserService {
|
return new (class BrowserService {
|
||||||
/**
|
/**
|
||||||
* Keyboard events
|
* Keyboard events
|
||||||
*/
|
*/
|
||||||
|
@ -490,5 +490,5 @@ export async function BrowserProvider({ getService }: FtrProviderContext) {
|
||||||
await driver.executeScript('document.body.scrollLeft = ' + scrollSize);
|
await driver.executeScript('document.body.scrollLeft = ' + scrollSize);
|
||||||
return this.getScrollLeft();
|
return this.getScrollLeft();
|
||||||
}
|
}
|
||||||
}();
|
})();
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ export async function VisualTestingProvider({ getService }: FtrProviderContext)
|
||||||
return statsCache.get(test)!;
|
return statsCache.get(test)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new class VisualTesting {
|
return new (class VisualTesting {
|
||||||
public async snapshot(name?: string) {
|
public async snapshot(name?: string) {
|
||||||
log.debug('Capturing percy snapshot');
|
log.debug('Capturing percy snapshot');
|
||||||
|
|
||||||
|
@ -84,5 +84,5 @@ export async function VisualTestingProvider({ getService }: FtrProviderContext)
|
||||||
? snapshot
|
? snapshot
|
||||||
: await browser.execute<[], string>(takePercySnapshotWithAgent);
|
: await browser.execute<[], string>(takePercySnapshotWithAgent);
|
||||||
}
|
}
|
||||||
}();
|
})();
|
||||||
}
|
}
|
||||||
|
|
2
typings/index.d.ts
vendored
2
typings/index.d.ts
vendored
|
@ -24,7 +24,7 @@ declare module '*.html' {
|
||||||
}
|
}
|
||||||
|
|
||||||
type MethodKeysOf<T> = {
|
type MethodKeysOf<T> = {
|
||||||
[K in keyof T]: T[K] extends (...args: any[]) => any ? K : never
|
[K in keyof T]: T[K] extends (...args: any[]) => any ? K : never;
|
||||||
}[keyof T];
|
}[keyof T];
|
||||||
|
|
||||||
type PublicMethodsOf<T> = Pick<T, MethodKeysOf<T>>;
|
type PublicMethodsOf<T> = Pick<T, MethodKeysOf<T>>;
|
||||||
|
|
|
@ -95,9 +95,7 @@ export class AlertsClient {
|
||||||
// Skip the cleanup error and throw the task manager error to avoid confusion
|
// Skip the cleanup error and throw the task manager error to avoid confusion
|
||||||
this.log(
|
this.log(
|
||||||
['alerting', 'error'],
|
['alerting', 'error'],
|
||||||
`Failed to cleanup alert "${createdAlert.id}" after scheduling task failed. Error: ${
|
`Failed to cleanup alert "${createdAlert.id}" after scheduling task failed. Error: ${err.message}`
|
||||||
err.message
|
|
||||||
}`
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
|
|
|
@ -65,35 +65,29 @@ export function ErrorGroupDetails() {
|
||||||
const { urlParams, uiFilters } = useUrlParams();
|
const { urlParams, uiFilters } = useUrlParams();
|
||||||
const { serviceName, start, end, errorGroupId } = urlParams;
|
const { serviceName, start, end, errorGroupId } = urlParams;
|
||||||
|
|
||||||
const { data: errorGroupData } = useFetcher(
|
const { data: errorGroupData } = useFetcher(() => {
|
||||||
() => {
|
if (serviceName && start && end && errorGroupId) {
|
||||||
if (serviceName && start && end && errorGroupId) {
|
return loadErrorGroupDetails({
|
||||||
return loadErrorGroupDetails({
|
serviceName,
|
||||||
serviceName,
|
start,
|
||||||
start,
|
end,
|
||||||
end,
|
errorGroupId,
|
||||||
errorGroupId,
|
uiFilters
|
||||||
uiFilters
|
});
|
||||||
});
|
}
|
||||||
}
|
}, [serviceName, start, end, errorGroupId, uiFilters]);
|
||||||
},
|
|
||||||
[serviceName, start, end, errorGroupId, uiFilters]
|
|
||||||
);
|
|
||||||
|
|
||||||
const { data: errorDistributionData } = useFetcher(
|
const { data: errorDistributionData } = useFetcher(() => {
|
||||||
() => {
|
if (serviceName && start && end && errorGroupId) {
|
||||||
if (serviceName && start && end && errorGroupId) {
|
return loadErrorDistribution({
|
||||||
return loadErrorDistribution({
|
serviceName,
|
||||||
serviceName,
|
start,
|
||||||
start,
|
end,
|
||||||
end,
|
errorGroupId,
|
||||||
errorGroupId,
|
uiFilters
|
||||||
uiFilters
|
});
|
||||||
});
|
}
|
||||||
}
|
}, [serviceName, start, end, errorGroupId, uiFilters]);
|
||||||
},
|
|
||||||
[serviceName, start, end, errorGroupId, uiFilters]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!errorGroupData || !errorDistributionData) {
|
if (!errorGroupData || !errorDistributionData) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -35,35 +35,29 @@ const ErrorGroupOverview: React.SFC<ErrorGroupOverviewProps> = ({
|
||||||
}) => {
|
}) => {
|
||||||
const { serviceName, start, end, sortField, sortDirection } = urlParams;
|
const { serviceName, start, end, sortField, sortDirection } = urlParams;
|
||||||
const uiFilters = useUiFilters(urlParams);
|
const uiFilters = useUiFilters(urlParams);
|
||||||
const { data: errorDistributionData } = useFetcher(
|
const { data: errorDistributionData } = useFetcher(() => {
|
||||||
() => {
|
if (serviceName && start && end) {
|
||||||
if (serviceName && start && end) {
|
return loadErrorDistribution({
|
||||||
return loadErrorDistribution({
|
serviceName,
|
||||||
serviceName,
|
start,
|
||||||
start,
|
end,
|
||||||
end,
|
uiFilters
|
||||||
uiFilters
|
});
|
||||||
});
|
}
|
||||||
}
|
}, [serviceName, start, end, uiFilters]);
|
||||||
},
|
|
||||||
[serviceName, start, end, uiFilters]
|
|
||||||
);
|
|
||||||
|
|
||||||
const { data: errorGroupListData } = useFetcher(
|
const { data: errorGroupListData } = useFetcher(() => {
|
||||||
() => {
|
if (serviceName && start && end) {
|
||||||
if (serviceName && start && end) {
|
return loadErrorGroupList({
|
||||||
return loadErrorGroupList({
|
serviceName,
|
||||||
serviceName,
|
start,
|
||||||
start,
|
end,
|
||||||
end,
|
sortField,
|
||||||
sortField,
|
sortDirection,
|
||||||
sortDirection,
|
uiFilters
|
||||||
uiFilters
|
});
|
||||||
});
|
}
|
||||||
}
|
}, [serviceName, start, end, sortField, sortDirection, uiFilters]);
|
||||||
},
|
|
||||||
[serviceName, start, end, sortField, sortDirection, uiFilters]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!errorDistributionData || !errorGroupListData) {
|
if (!errorDistributionData || !errorGroupListData) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -17,14 +17,11 @@ import { useUrlParams } from '../../../hooks/useUrlParams';
|
||||||
export function ServiceDetails() {
|
export function ServiceDetails() {
|
||||||
const { urlParams, uiFilters } = useUrlParams();
|
const { urlParams, uiFilters } = useUrlParams();
|
||||||
const { serviceName, start, end } = urlParams;
|
const { serviceName, start, end } = urlParams;
|
||||||
const { data: serviceDetailsData } = useFetcher(
|
const { data: serviceDetailsData } = useFetcher(() => {
|
||||||
() => {
|
if (serviceName && start && end) {
|
||||||
if (serviceName && start && end) {
|
return loadServiceDetails({ serviceName, start, end, uiFilters });
|
||||||
return loadServiceDetails({ serviceName, start, end, uiFilters });
|
}
|
||||||
}
|
}, [serviceName, start, end, uiFilters]);
|
||||||
},
|
|
||||||
[serviceName, start, end, uiFilters]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!serviceDetailsData) {
|
if (!serviceDetailsData) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -30,51 +30,45 @@ export function ServiceOverview() {
|
||||||
urlParams: { start, end },
|
urlParams: { start, end },
|
||||||
uiFilters
|
uiFilters
|
||||||
} = useUrlParams();
|
} = useUrlParams();
|
||||||
const { data = initalData } = useFetcher(
|
const { data = initalData } = useFetcher(() => {
|
||||||
() => {
|
if (start && end) {
|
||||||
if (start && end) {
|
return loadServiceList({ start, end, uiFilters });
|
||||||
return loadServiceList({ start, end, uiFilters });
|
}
|
||||||
}
|
}, [start, end, uiFilters]);
|
||||||
},
|
|
||||||
[start, end, uiFilters]
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
if (data.hasLegacyData && !hasDisplayedToast) {
|
||||||
if (data.hasLegacyData && !hasDisplayedToast) {
|
hasDisplayedToast = true;
|
||||||
hasDisplayedToast = true;
|
toastNotifications.addWarning({
|
||||||
toastNotifications.addWarning({
|
title: i18n.translate('xpack.apm.serviceOverview.toastTitle', {
|
||||||
title: i18n.translate('xpack.apm.serviceOverview.toastTitle', {
|
defaultMessage:
|
||||||
defaultMessage:
|
'Legacy data was detected within the selected time range'
|
||||||
'Legacy data was detected within the selected time range'
|
}),
|
||||||
}),
|
text: (
|
||||||
text: (
|
<p>
|
||||||
<p>
|
{i18n.translate('xpack.apm.serviceOverview.toastText', {
|
||||||
{i18n.translate('xpack.apm.serviceOverview.toastText', {
|
defaultMessage:
|
||||||
defaultMessage:
|
"You're running Elastic Stack 7.0+ and we've detected incompatible data from a previous 6.x version. If you want to view this data in APM, you should migrate it. See more in "
|
||||||
"You're running Elastic Stack 7.0+ and we've detected incompatible data from a previous 6.x version. If you want to view this data in APM, you should migrate it. See more in "
|
})}
|
||||||
|
|
||||||
|
<EuiLink
|
||||||
|
href={url.format({
|
||||||
|
pathname: chrome.addBasePath('/app/kibana'),
|
||||||
|
hash: '/management/elasticsearch/upgrade_assistant'
|
||||||
})}
|
})}
|
||||||
|
>
|
||||||
<EuiLink
|
{i18n.translate(
|
||||||
href={url.format({
|
'xpack.apm.serviceOverview.upgradeAssistantLink',
|
||||||
pathname: chrome.addBasePath('/app/kibana'),
|
{
|
||||||
hash: '/management/elasticsearch/upgrade_assistant'
|
defaultMessage: 'the upgrade assistant'
|
||||||
})}
|
}
|
||||||
>
|
)}
|
||||||
{i18n.translate(
|
</EuiLink>
|
||||||
'xpack.apm.serviceOverview.upgradeAssistantLink',
|
</p>
|
||||||
{
|
)
|
||||||
defaultMessage: 'the upgrade assistant'
|
});
|
||||||
}
|
}
|
||||||
)}
|
}, [data.hasLegacyData]);
|
||||||
</EuiLink>
|
|
||||||
</p>
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[data.hasLegacyData]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EuiPanel>
|
<EuiPanel>
|
||||||
|
|
|
@ -14,14 +14,11 @@ import { useUrlParams } from '../../../hooks/useUrlParams';
|
||||||
export function TraceOverview() {
|
export function TraceOverview() {
|
||||||
const { urlParams, uiFilters } = useUrlParams();
|
const { urlParams, uiFilters } = useUrlParams();
|
||||||
const { start, end } = urlParams;
|
const { start, end } = urlParams;
|
||||||
const { status, data = [] } = useFetcher(
|
const { status, data = [] } = useFetcher(() => {
|
||||||
() => {
|
if (start && end) {
|
||||||
if (start && end) {
|
return loadTraceList({ start, end, uiFilters });
|
||||||
return loadTraceList({ start, end, uiFilters });
|
}
|
||||||
}
|
}, [start, end, uiFilters]);
|
||||||
},
|
|
||||||
[start, end, uiFilters]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EuiPanel>
|
<EuiPanel>
|
||||||
|
|
|
@ -110,48 +110,42 @@ export const TransactionDistribution: FunctionComponent<Props> = (
|
||||||
transactionType
|
transactionType
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const redirectToDefaultSample = useCallback(
|
const redirectToDefaultSample = useCallback(() => {
|
||||||
() => {
|
const defaultSample =
|
||||||
const defaultSample =
|
distribution && distribution.defaultSample
|
||||||
distribution && distribution.defaultSample
|
? distribution.defaultSample
|
||||||
? distribution.defaultSample
|
: {};
|
||||||
: {};
|
|
||||||
|
|
||||||
const parsedQueryParams = toQuery(history.location.search);
|
const parsedQueryParams = toQuery(history.location.search);
|
||||||
|
|
||||||
history.replace({
|
history.replace({
|
||||||
...history.location,
|
...history.location,
|
||||||
search: fromQuery({
|
search: fromQuery({
|
||||||
...omit(parsedQueryParams, 'transactionId', 'traceId'),
|
...omit(parsedQueryParams, 'transactionId', 'traceId'),
|
||||||
...defaultSample
|
...defaultSample
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
},
|
}, [distribution, loading]);
|
||||||
[distribution, loading]
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
if (loading) {
|
||||||
if (loading) {
|
return;
|
||||||
return;
|
}
|
||||||
}
|
const selectedSampleIsAvailable = distribution
|
||||||
const selectedSampleIsAvailable = distribution
|
? !!distribution.buckets.find(
|
||||||
? !!distribution.buckets.find(
|
bucket =>
|
||||||
bucket =>
|
!!(
|
||||||
!!(
|
bucket.sample &&
|
||||||
bucket.sample &&
|
bucket.sample.transactionId === transactionId &&
|
||||||
bucket.sample.transactionId === transactionId &&
|
bucket.sample.traceId === traceId
|
||||||
bucket.sample.traceId === traceId
|
)
|
||||||
)
|
)
|
||||||
)
|
: false;
|
||||||
: false;
|
|
||||||
|
|
||||||
if (!selectedSampleIsAvailable && !!distribution) {
|
if (!selectedSampleIsAvailable && !!distribution) {
|
||||||
redirectToDefaultSample();
|
redirectToDefaultSample();
|
||||||
}
|
}
|
||||||
},
|
}, [distribution, transactionId, traceId, redirectToDefaultSample, loading]);
|
||||||
[distribution, transactionId, traceId, redirectToDefaultSample, loading]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!distribution || !distribution.totalHits || !traceId || !transactionId) {
|
if (!distribution || !distribution.totalHits || !traceId || !transactionId) {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -55,9 +55,7 @@ export const ErrorCountBadge: React.SFC<Props> = ({
|
||||||
path={`/${idx(transaction, _ => _.service.name)}/errors`}
|
path={`/${idx(transaction, _ => _.service.name)}/errors`}
|
||||||
query={{
|
query={{
|
||||||
kuery: encodeURIComponent(
|
kuery: encodeURIComponent(
|
||||||
`trace.id : "${transaction.trace.id}" and transaction.id : "${
|
`trace.id : "${transaction.trace.id}" and transaction.id : "${transaction.transaction.id}"`
|
||||||
transaction.transaction.id
|
|
||||||
}"`
|
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
color="danger"
|
color="danger"
|
||||||
|
|
|
@ -29,16 +29,13 @@ export const TruncateHeightSection: React.SFC<Props> = ({
|
||||||
const [showToggle, setShowToggle] = useState(true);
|
const [showToggle, setShowToggle] = useState(true);
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
if (contentContainerEl.current) {
|
||||||
if (contentContainerEl.current) {
|
const shouldShow =
|
||||||
const shouldShow =
|
contentContainerEl.current.scrollHeight > previewHeight;
|
||||||
contentContainerEl.current.scrollHeight > previewHeight;
|
setShowToggle(shouldShow);
|
||||||
setShowToggle(shouldShow);
|
}
|
||||||
}
|
}, [children, previewHeight]);
|
||||||
},
|
|
||||||
[children, previewHeight]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
|
|
|
@ -79,18 +79,15 @@ export const EnvironmentFilter: React.FC = () => {
|
||||||
const { start, end, serviceName } = urlParams;
|
const { start, end, serviceName } = urlParams;
|
||||||
|
|
||||||
const { environment } = uiFilters;
|
const { environment } = uiFilters;
|
||||||
const { data: environments = [], status = 'loading' } = useFetcher(
|
const { data: environments = [], status = 'loading' } = useFetcher(() => {
|
||||||
() => {
|
if (start && end) {
|
||||||
if (start && end) {
|
return loadEnvironmentsFilter({
|
||||||
return loadEnvironmentsFilter({
|
start,
|
||||||
start,
|
end,
|
||||||
end,
|
serviceName
|
||||||
serviceName
|
});
|
||||||
});
|
}
|
||||||
}
|
}, [start, end, serviceName]);
|
||||||
},
|
|
||||||
[start, end, serviceName]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EuiSelect
|
<EuiSelect
|
||||||
|
|
|
@ -25,20 +25,17 @@ const TransactionBreakdownGraph: React.FC<Props> = props => {
|
||||||
|
|
||||||
const series: React.ComponentProps<
|
const series: React.ComponentProps<
|
||||||
typeof TransactionLineChart
|
typeof TransactionLineChart
|
||||||
>['series'] = useMemo(
|
>['series'] = useMemo(() => {
|
||||||
() => {
|
return timeseries.map(timeseriesConfig => {
|
||||||
return timeseries.map(timeseriesConfig => {
|
return {
|
||||||
return {
|
title: timeseriesConfig.name,
|
||||||
title: timeseriesConfig.name,
|
color: timeseriesConfig.color,
|
||||||
color: timeseriesConfig.color,
|
data: timeseriesConfig.values,
|
||||||
data: timeseriesConfig.values,
|
type: 'area',
|
||||||
type: 'area',
|
hideLegend: true
|
||||||
hideLegend: true
|
};
|
||||||
};
|
}, {});
|
||||||
}, {});
|
}, [timeseries]);
|
||||||
},
|
|
||||||
[timeseries]
|
|
||||||
);
|
|
||||||
|
|
||||||
const tickFormatY = useCallback((y: number | null) => {
|
const tickFormatY = useCallback((y: number | null) => {
|
||||||
return numeral(y || 0).format('0 %');
|
return numeral(y || 0).format('0 %');
|
||||||
|
|
|
@ -51,62 +51,53 @@ const TransactionBreakdown: React.FC<{
|
||||||
const kpis = data ? data.kpis : undefined;
|
const kpis = data ? data.kpis : undefined;
|
||||||
const timeseriesPerSubtype = data ? data.timeseries_per_subtype : undefined;
|
const timeseriesPerSubtype = data ? data.timeseries_per_subtype : undefined;
|
||||||
|
|
||||||
const legends = useMemo(
|
const legends = useMemo(() => {
|
||||||
() => {
|
const names = kpis ? kpis.map(kpi => kpi.name).sort() : [];
|
||||||
const names = kpis ? kpis.map(kpi => kpi.name).sort() : [];
|
|
||||||
|
|
||||||
return names.map((name, index) => {
|
return names.map((name, index) => {
|
||||||
return {
|
return {
|
||||||
name,
|
name,
|
||||||
color: COLORS[index % COLORS.length]
|
color: COLORS[index % COLORS.length]
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
}, [kpis]);
|
||||||
[kpis]
|
|
||||||
);
|
|
||||||
|
|
||||||
const sortedAndColoredKpis = useMemo(
|
const sortedAndColoredKpis = useMemo(() => {
|
||||||
() => {
|
if (!kpis) {
|
||||||
if (!kpis) {
|
return null;
|
||||||
return null;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return legends.map(legend => {
|
return legends.map(legend => {
|
||||||
const { color } = legend;
|
const { color } = legend;
|
||||||
|
|
||||||
const breakdown = kpis.find(
|
const breakdown = kpis.find(
|
||||||
b => b.name === legend.name
|
b => b.name === legend.name
|
||||||
) as typeof kpis[0];
|
) as typeof kpis[0];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...breakdown,
|
...breakdown,
|
||||||
color
|
color
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
}, [kpis, legends]);
|
||||||
[kpis, legends]
|
|
||||||
);
|
|
||||||
|
|
||||||
const loading = status === FETCH_STATUS.LOADING || status === undefined;
|
const loading = status === FETCH_STATUS.LOADING || status === undefined;
|
||||||
|
|
||||||
const hasHits = data && data.kpis.length > 0;
|
const hasHits = data && data.kpis.length > 0;
|
||||||
const timeseries = useMemo(
|
const timeseries = useMemo(() => {
|
||||||
() => {
|
if (!timeseriesPerSubtype) {
|
||||||
if (!timeseriesPerSubtype) {
|
return [];
|
||||||
return [];
|
}
|
||||||
}
|
return legends.map(legend => {
|
||||||
return legends.map(legend => {
|
const series = timeseriesPerSubtype[legend.name];
|
||||||
const series = timeseriesPerSubtype[legend.name];
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: legend.name,
|
name: legend.name,
|
||||||
values: series,
|
values: series,
|
||||||
color: legend.color
|
color: legend.color
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
}, [timeseriesPerSubtype, legends]);
|
||||||
[timeseriesPerSubtype, legends]
|
|
||||||
);
|
|
||||||
|
|
||||||
return receivedDataDuringLifetime ? (
|
return receivedDataDuringLifetime ? (
|
||||||
<EuiPanel>
|
<EuiPanel>
|
||||||
|
|
|
@ -56,37 +56,34 @@ const TransactionLineChart: React.FC<Props> = (props: Props) => {
|
||||||
);
|
);
|
||||||
const { time, setTime } = useChartsTime();
|
const { time, setTime } = useChartsTime();
|
||||||
|
|
||||||
const hoverXHandlers = useMemo(
|
const hoverXHandlers = useMemo(() => {
|
||||||
() => {
|
return {
|
||||||
return {
|
onHover: (hoverX: number) => {
|
||||||
onHover: (hoverX: number) => {
|
setTime(hoverX);
|
||||||
setTime(hoverX);
|
},
|
||||||
},
|
onMouseLeave: () => {
|
||||||
onMouseLeave: () => {
|
setTime(null);
|
||||||
setTime(null);
|
},
|
||||||
},
|
onSelectionEnd: (range: { start: number; end: number }) => {
|
||||||
onSelectionEnd: (range: { start: number; end: number }) => {
|
setTime(null);
|
||||||
setTime(null);
|
|
||||||
|
|
||||||
const currentSearch = toQuery(history.location.search);
|
const currentSearch = toQuery(history.location.search);
|
||||||
const nextSearch = {
|
const nextSearch = {
|
||||||
rangeFrom: new Date(range.start).toISOString(),
|
rangeFrom: new Date(range.start).toISOString(),
|
||||||
rangeTo: new Date(range.end).toISOString()
|
rangeTo: new Date(range.end).toISOString()
|
||||||
};
|
};
|
||||||
|
|
||||||
history.push({
|
history.push({
|
||||||
...history.location,
|
...history.location,
|
||||||
search: fromQuery({
|
search: fromQuery({
|
||||||
...currentSearch,
|
...currentSearch,
|
||||||
...nextSearch
|
...nextSearch
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
hoverX: time
|
hoverX: time
|
||||||
};
|
};
|
||||||
},
|
}, [time, setTime]);
|
||||||
[time, setTime]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!start || !end) {
|
if (!start || !end) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -16,35 +16,29 @@ export function useDelayedVisibility(
|
||||||
const [isVisible, setIsVisible] = useState(false);
|
const [isVisible, setIsVisible] = useState(false);
|
||||||
const delayedRef = useRef<Delayed | null>(null);
|
const delayedRef = useRef<Delayed | null>(null);
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
const delayed = new Delayed({
|
||||||
const delayed = new Delayed({
|
hideDelayMs,
|
||||||
hideDelayMs,
|
showDelayMs,
|
||||||
showDelayMs,
|
minimumVisibleDuration
|
||||||
minimumVisibleDuration
|
});
|
||||||
});
|
delayed.onChange(visibility => {
|
||||||
delayed.onChange(visibility => {
|
setIsVisible(visibility);
|
||||||
setIsVisible(visibility);
|
});
|
||||||
});
|
delayedRef.current = delayed;
|
||||||
delayedRef.current = delayed;
|
}, [hideDelayMs, showDelayMs, minimumVisibleDuration]);
|
||||||
},
|
|
||||||
[hideDelayMs, showDelayMs, minimumVisibleDuration]
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
if (!delayedRef.current) {
|
||||||
if (!delayedRef.current) {
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (visible) {
|
if (visible) {
|
||||||
delayedRef.current.show();
|
delayedRef.current.show();
|
||||||
} else {
|
} else {
|
||||||
delayedRef.current.hide();
|
delayedRef.current.hide();
|
||||||
}
|
}
|
||||||
},
|
}, [visible]);
|
||||||
[visible]
|
|
||||||
);
|
|
||||||
|
|
||||||
return isVisible;
|
return isVisible;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,15 +14,12 @@ const ChartsTimeContext = React.createContext<{
|
||||||
const ChartsTimeContextProvider: React.FC = ({ children }) => {
|
const ChartsTimeContextProvider: React.FC = ({ children }) => {
|
||||||
const [time, setTime] = useState<number | null>(null);
|
const [time, setTime] = useState<number | null>(null);
|
||||||
|
|
||||||
const value = useMemo(
|
const value = useMemo(() => {
|
||||||
() => {
|
return {
|
||||||
return {
|
time,
|
||||||
time,
|
setTime
|
||||||
setTime
|
};
|
||||||
};
|
}, [time, setTime]);
|
||||||
},
|
|
||||||
[time, setTime]
|
|
||||||
);
|
|
||||||
|
|
||||||
return <ChartsTimeContext.Provider value={value} children={children} />;
|
return <ChartsTimeContext.Provider value={value} children={children} />;
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,16 +15,13 @@ export const MatchedRouteContext = React.createContext<Array<typeof routes[0]>>(
|
||||||
export const MatchedRouteProvider: React.FC = ({ children }) => {
|
export const MatchedRouteProvider: React.FC = ({ children }) => {
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
|
|
||||||
const contextValue = useMemo(
|
const contextValue = useMemo(() => {
|
||||||
() => {
|
return routes.filter(route => {
|
||||||
return routes.filter(route => {
|
return matchPath(pathname, {
|
||||||
return matchPath(pathname, {
|
path: route.path
|
||||||
path: route.path
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
},
|
});
|
||||||
[pathname]
|
}, [pathname]);
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MatchedRouteContext.Provider value={contextValue} children={children} />
|
<MatchedRouteContext.Provider value={contextValue} children={children} />
|
||||||
|
|
|
@ -69,16 +69,13 @@ const UrlParamsProvider: React.ComponentClass<{}> = withRouter(
|
||||||
|
|
||||||
const uiFilters = useUiFilters(urlParams);
|
const uiFilters = useUiFilters(urlParams);
|
||||||
|
|
||||||
const contextValue = useMemo(
|
const contextValue = useMemo(() => {
|
||||||
() => {
|
return {
|
||||||
return {
|
urlParams,
|
||||||
urlParams,
|
refreshTimeRange,
|
||||||
refreshTimeRange,
|
uiFilters
|
||||||
uiFilters
|
};
|
||||||
};
|
}, [urlParams, refreshTimeRange, uiFilters]);
|
||||||
},
|
|
||||||
[urlParams, refreshTimeRange, uiFilters]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UrlParamsContext.Provider children={children} value={contextValue} />
|
<UrlParamsContext.Provider children={children} value={contextValue} />
|
||||||
|
|
|
@ -43,15 +43,12 @@ describe('when simulating race condition', () => {
|
||||||
ms: number;
|
ms: number;
|
||||||
renderFn: any;
|
renderFn: any;
|
||||||
}) {
|
}) {
|
||||||
const { data, status, error } = useFetcher(
|
const { data, status, error } = useFetcher(async () => {
|
||||||
async () => {
|
requestCallOrder.push(['request', name, ms]);
|
||||||
requestCallOrder.push(['request', name, ms]);
|
const res = await asyncFn(name, ms);
|
||||||
const res = await asyncFn(name, ms);
|
requestCallOrder.push(['response', name, ms]);
|
||||||
requestCallOrder.push(['response', name, ms]);
|
return res;
|
||||||
return res;
|
}, [name, ms]);
|
||||||
},
|
|
||||||
[name, ms]
|
|
||||||
);
|
|
||||||
renderFn({ data, status, error });
|
renderFn({ data, status, error });
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,55 +29,52 @@ export function useFetcher<Response>(
|
||||||
}>({});
|
}>({});
|
||||||
const [counter, setCounter] = useState(0);
|
const [counter, setCounter] = useState(0);
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
let didCancel = false;
|
||||||
let didCancel = false;
|
|
||||||
|
|
||||||
async function doFetch() {
|
async function doFetch() {
|
||||||
const promise = fn();
|
const promise = fn();
|
||||||
if (!promise) {
|
if (!promise) {
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
dispatchStatus({ id, isLoading: true });
|
|
||||||
|
|
||||||
setResult({
|
|
||||||
data: preservePreviousResponse ? result.data : undefined, // preserve data from previous state while loading next state
|
|
||||||
status: FETCH_STATUS.LOADING,
|
|
||||||
error: undefined
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
const data = await promise;
|
|
||||||
if (!didCancel) {
|
|
||||||
dispatchStatus({ id, isLoading: false });
|
|
||||||
setResult({
|
|
||||||
data,
|
|
||||||
status: FETCH_STATUS.SUCCESS,
|
|
||||||
error: undefined
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
if (!didCancel) {
|
|
||||||
dispatchStatus({ id, isLoading: false });
|
|
||||||
setResult({
|
|
||||||
data: undefined,
|
|
||||||
status: FETCH_STATUS.FAILURE,
|
|
||||||
error: e
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
doFetch();
|
dispatchStatus({ id, isLoading: true });
|
||||||
|
|
||||||
return () => {
|
setResult({
|
||||||
dispatchStatus({ id, isLoading: false });
|
data: preservePreviousResponse ? result.data : undefined, // preserve data from previous state while loading next state
|
||||||
didCancel = true;
|
status: FETCH_STATUS.LOADING,
|
||||||
};
|
error: undefined
|
||||||
},
|
});
|
||||||
[...effectKey, counter]
|
|
||||||
);
|
try {
|
||||||
|
const data = await promise;
|
||||||
|
if (!didCancel) {
|
||||||
|
dispatchStatus({ id, isLoading: false });
|
||||||
|
setResult({
|
||||||
|
data,
|
||||||
|
status: FETCH_STATUS.SUCCESS,
|
||||||
|
error: undefined
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (!didCancel) {
|
||||||
|
dispatchStatus({ id, isLoading: false });
|
||||||
|
setResult({
|
||||||
|
data: undefined,
|
||||||
|
status: FETCH_STATUS.FAILURE,
|
||||||
|
error: e
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
doFetch();
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
dispatchStatus({ id, isLoading: false });
|
||||||
|
didCancel = true;
|
||||||
|
};
|
||||||
|
}, [...effectKey, counter]);
|
||||||
|
|
||||||
return useMemo(
|
return useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
|
|
|
@ -22,20 +22,17 @@ export function useServiceMetricCharts(
|
||||||
const uiFilters = useUiFilters(urlParams);
|
const uiFilters = useUiFilters(urlParams);
|
||||||
const { data = INITIAL_DATA, error, status } = useFetcher<
|
const { data = INITIAL_DATA, error, status } = useFetcher<
|
||||||
MetricsChartsByAgentAPIResponse
|
MetricsChartsByAgentAPIResponse
|
||||||
>(
|
>(() => {
|
||||||
() => {
|
if (serviceName && start && end && agentName) {
|
||||||
if (serviceName && start && end && agentName) {
|
return loadMetricsChartData({
|
||||||
return loadMetricsChartData({
|
serviceName,
|
||||||
serviceName,
|
start,
|
||||||
start,
|
end,
|
||||||
end,
|
agentName,
|
||||||
agentName,
|
uiFilters
|
||||||
uiFilters
|
});
|
||||||
});
|
}
|
||||||
}
|
}, [serviceName, start, end, agentName, uiFilters]);
|
||||||
},
|
|
||||||
[serviceName, start, end, agentName, uiFilters]
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data,
|
data,
|
||||||
|
|
|
@ -17,22 +17,19 @@ export function useTransactionBreakdown() {
|
||||||
uiFilters
|
uiFilters
|
||||||
} = useUrlParams();
|
} = useUrlParams();
|
||||||
|
|
||||||
const { data, error, status } = useFetcher(
|
const { data, error, status } = useFetcher(async () => {
|
||||||
async () => {
|
if (serviceName && start && end) {
|
||||||
if (serviceName && start && end) {
|
return callApi<TransactionBreakdownAPIResponse>({
|
||||||
return callApi<TransactionBreakdownAPIResponse>({
|
pathname: `/api/apm/services/${serviceName}/transaction_groups/breakdown`,
|
||||||
pathname: `/api/apm/services/${serviceName}/transaction_groups/breakdown`,
|
query: {
|
||||||
query: {
|
start,
|
||||||
start,
|
end,
|
||||||
end,
|
transactionName,
|
||||||
transactionName,
|
uiFiltersES: await getUiFiltersES(uiFilters)
|
||||||
uiFiltersES: await getUiFiltersES(uiFilters)
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
}
|
}, [serviceName, start, end, uiFilters]);
|
||||||
},
|
|
||||||
[serviceName, start, end, uiFilters]
|
|
||||||
);
|
|
||||||
|
|
||||||
const receivedDataDuringLifetime = useRef(false);
|
const receivedDataDuringLifetime = useRef(false);
|
||||||
|
|
||||||
|
|
|
@ -21,21 +21,18 @@ export function useTransactionDetailsCharts(urlParams: IUrlParams) {
|
||||||
} = urlParams;
|
} = urlParams;
|
||||||
const uiFilters = useUiFilters(urlParams);
|
const uiFilters = useUiFilters(urlParams);
|
||||||
|
|
||||||
const { data, error, status } = useFetcher(
|
const { data, error, status } = useFetcher(() => {
|
||||||
() => {
|
if (serviceName && start && end && transactionName && transactionType) {
|
||||||
if (serviceName && start && end && transactionName && transactionType) {
|
return loadTransactionCharts({
|
||||||
return loadTransactionCharts({
|
serviceName,
|
||||||
serviceName,
|
start,
|
||||||
start,
|
end,
|
||||||
end,
|
transactionName,
|
||||||
transactionName,
|
transactionType,
|
||||||
transactionType,
|
uiFilters
|
||||||
uiFilters
|
});
|
||||||
});
|
}
|
||||||
}
|
}, [serviceName, start, end, transactionName, transactionType, uiFilters]);
|
||||||
},
|
|
||||||
[serviceName, start, end, transactionName, transactionType, uiFilters]
|
|
||||||
);
|
|
||||||
|
|
||||||
const memoizedData = useMemo(() => getTransactionCharts(urlParams, data), [
|
const memoizedData = useMemo(() => getTransactionCharts(urlParams, data), [
|
||||||
data
|
data
|
||||||
|
|
|
@ -28,32 +28,29 @@ export function useTransactionDistribution(urlParams: IUrlParams) {
|
||||||
} = urlParams;
|
} = urlParams;
|
||||||
const uiFilters = useUiFilters(urlParams);
|
const uiFilters = useUiFilters(urlParams);
|
||||||
|
|
||||||
const { data = INITIAL_DATA, status, error } = useFetcher(
|
const { data = INITIAL_DATA, status, error } = useFetcher(() => {
|
||||||
() => {
|
if (serviceName && start && end && transactionType && transactionName) {
|
||||||
if (serviceName && start && end && transactionType && transactionName) {
|
return loadTransactionDistribution({
|
||||||
return loadTransactionDistribution({
|
serviceName,
|
||||||
serviceName,
|
start,
|
||||||
start,
|
end,
|
||||||
end,
|
transactionType,
|
||||||
transactionType,
|
transactionName,
|
||||||
transactionName,
|
transactionId,
|
||||||
transactionId,
|
traceId,
|
||||||
traceId,
|
uiFilters
|
||||||
uiFilters
|
});
|
||||||
});
|
}
|
||||||
}
|
}, [
|
||||||
},
|
serviceName,
|
||||||
[
|
start,
|
||||||
serviceName,
|
end,
|
||||||
start,
|
transactionType,
|
||||||
end,
|
transactionName,
|
||||||
transactionType,
|
transactionId,
|
||||||
transactionName,
|
traceId,
|
||||||
transactionId,
|
uiFilters
|
||||||
traceId,
|
]);
|
||||||
uiFilters
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
return { data, status, error };
|
return { data, status, error };
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,20 +43,17 @@ function getWithRelativeImpact(items: TransactionListAPIResponse) {
|
||||||
export function useTransactionList(urlParams: IUrlParams) {
|
export function useTransactionList(urlParams: IUrlParams) {
|
||||||
const { serviceName, transactionType, start, end } = urlParams;
|
const { serviceName, transactionType, start, end } = urlParams;
|
||||||
const uiFilters = useUiFilters(urlParams);
|
const uiFilters = useUiFilters(urlParams);
|
||||||
const { data = [], error, status } = useFetcher(
|
const { data = [], error, status } = useFetcher(() => {
|
||||||
() => {
|
if (serviceName && start && end && transactionType) {
|
||||||
if (serviceName && start && end && transactionType) {
|
return loadTransactionList({
|
||||||
return loadTransactionList({
|
serviceName,
|
||||||
serviceName,
|
start,
|
||||||
start,
|
end,
|
||||||
end,
|
transactionType,
|
||||||
transactionType,
|
uiFilters
|
||||||
uiFilters
|
});
|
||||||
});
|
}
|
||||||
}
|
}, [serviceName, start, end, transactionType, uiFilters]);
|
||||||
},
|
|
||||||
[serviceName, start, end, transactionType, uiFilters]
|
|
||||||
);
|
|
||||||
|
|
||||||
const memoizedData = useMemo(() => getWithRelativeImpact(data), [data]);
|
const memoizedData = useMemo(() => getWithRelativeImpact(data), [data]);
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -15,20 +15,17 @@ export function useTransactionOverviewCharts(urlParams: IUrlParams) {
|
||||||
const { serviceName, start, end, transactionType } = urlParams;
|
const { serviceName, start, end, transactionType } = urlParams;
|
||||||
const uiFilters = useUiFilters(urlParams);
|
const uiFilters = useUiFilters(urlParams);
|
||||||
|
|
||||||
const { data, error, status } = useFetcher(
|
const { data, error, status } = useFetcher(() => {
|
||||||
() => {
|
if (serviceName && start && end) {
|
||||||
if (serviceName && start && end) {
|
return loadTransactionCharts({
|
||||||
return loadTransactionCharts({
|
serviceName,
|
||||||
serviceName,
|
start,
|
||||||
start,
|
end,
|
||||||
end,
|
transactionType,
|
||||||
transactionType,
|
uiFilters
|
||||||
uiFilters
|
});
|
||||||
});
|
}
|
||||||
}
|
}, [serviceName, start, end, transactionType, uiFilters]);
|
||||||
},
|
|
||||||
[serviceName, start, end, transactionType, uiFilters]
|
|
||||||
);
|
|
||||||
|
|
||||||
const memoizedData = useMemo(() => getTransactionCharts(urlParams, data), [
|
const memoizedData = useMemo(() => getTransactionCharts(urlParams, data), [
|
||||||
data
|
data
|
||||||
|
|
|
@ -14,14 +14,11 @@ const INITIAL_DATA = { trace: [], errorsPerTransaction: {} };
|
||||||
|
|
||||||
export function useWaterfall(urlParams: IUrlParams) {
|
export function useWaterfall(urlParams: IUrlParams) {
|
||||||
const { traceId, start, end, transactionId } = urlParams;
|
const { traceId, start, end, transactionId } = urlParams;
|
||||||
const { data = INITIAL_DATA, status, error } = useFetcher(
|
const { data = INITIAL_DATA, status, error } = useFetcher(() => {
|
||||||
() => {
|
if (traceId && start && end) {
|
||||||
if (traceId && start && end) {
|
return loadTrace({ traceId, start, end });
|
||||||
return loadTrace({ traceId, start, end });
|
}
|
||||||
}
|
}, [traceId, start, end]);
|
||||||
},
|
|
||||||
[traceId, start, end]
|
|
||||||
);
|
|
||||||
|
|
||||||
const waterfall = useMemo(() => getWaterfall(data, transactionId), [
|
const waterfall = useMemo(() => getWaterfall(data, transactionId), [
|
||||||
data,
|
data,
|
||||||
|
|
|
@ -29,7 +29,7 @@ declare module 'elasticsearch' {
|
||||||
export type AggregationOptionMap = {
|
export type AggregationOptionMap = {
|
||||||
aggs?: {
|
aggs?: {
|
||||||
[aggregationName: string]: {
|
[aggregationName: string]: {
|
||||||
[T in AggregationType]?: AggOptions & AggregationOptionMap
|
[T in AggregationType]?: AggOptions & AggregationOptionMap;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -99,7 +99,7 @@ declare module 'elasticsearch' {
|
||||||
lower: number;
|
lower: number;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}[AggregationType & keyof AggregationOption[AggregationName]]
|
}[AggregationType & keyof AggregationOption[AggregationName]];
|
||||||
}
|
}
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ import React, { Component, ReactNode } from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { BreadcrumbConsumer } from '../navigation/breadcrumb';
|
import { BreadcrumbConsumer } from '../navigation/breadcrumb';
|
||||||
|
|
||||||
type RenderCallback = ((component: () => JSX.Element) => void);
|
type RenderCallback = (component: () => JSX.Element) => void;
|
||||||
interface PrimaryLayoutProps {
|
interface PrimaryLayoutProps {
|
||||||
title: string | React.ReactNode;
|
title: string | React.ReactNode;
|
||||||
actionSection?: React.ReactNode;
|
actionSection?: React.ReactNode;
|
||||||
|
|
|
@ -86,9 +86,7 @@ export class BackendFrameworkLib {
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
error: {
|
error: {
|
||||||
message: `Your ${
|
message: `Your ${this.license.type} license does not support this API or is expired. Please upgrade your license.`,
|
||||||
this.license.type
|
|
||||||
} license does not support this API or is expired. Please upgrade your license.`,
|
|
||||||
code: 403,
|
code: 403,
|
||||||
},
|
},
|
||||||
success: false,
|
success: false,
|
||||||
|
|
|
@ -13,6 +13,4 @@ import * as eui from '@elastic/eui';
|
||||||
import { Moment } from 'moment';
|
import { Moment } from 'moment';
|
||||||
import { ChangeEventHandler, MouseEventHandler, ReactType, Ref, SFC } from 'react';
|
import { ChangeEventHandler, MouseEventHandler, ReactType, Ref, SFC } from 'react';
|
||||||
|
|
||||||
declare module '@elastic/eui' {
|
declare module '@elastic/eui' {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -19,8 +19,6 @@ export const horizontalProgressBar: ElementFactory = () => ({
|
||||||
expression: `filters
|
expression: `filters
|
||||||
| demodata
|
| demodata
|
||||||
| math "mean(percent_uptime)"
|
| math "mean(percent_uptime)"
|
||||||
| progress shape="horizontalBar" label={formatnumber 0%} font={font size=24 family="${
|
| progress shape="horizontalBar" label={formatnumber 0%} font={font size=24 family="${openSans.value}" color="#000000" align=center}
|
||||||
openSans.value
|
|
||||||
}" color="#000000" align=center}
|
|
||||||
| render`,
|
| render`,
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,8 +19,6 @@ export const horizontalProgressPill: ElementFactory = () => ({
|
||||||
expression: `filters
|
expression: `filters
|
||||||
| demodata
|
| demodata
|
||||||
| math "mean(percent_uptime)"
|
| math "mean(percent_uptime)"
|
||||||
| progress shape="horizontalPill" label={formatnumber 0%} font={font size=24 family="${
|
| progress shape="horizontalPill" label={formatnumber 0%} font={font size=24 family="${openSans.value}" color="#000000" align=center}
|
||||||
openSans.value
|
|
||||||
}" color="#000000" align=center}
|
|
||||||
| render`,
|
| render`,
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,8 +19,6 @@ export const progressGauge: ElementFactory = () => ({
|
||||||
expression: `filters
|
expression: `filters
|
||||||
| demodata
|
| demodata
|
||||||
| math "mean(percent_uptime)"
|
| math "mean(percent_uptime)"
|
||||||
| progress shape="gauge" label={formatnumber 0%} font={font size=24 family="${
|
| progress shape="gauge" label={formatnumber 0%} font={font size=24 family="${openSans.value}" color="#000000" align=center}
|
||||||
openSans.value
|
|
||||||
}" color="#000000" align=center}
|
|
||||||
| render`,
|
| render`,
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,8 +19,6 @@ export const progressSemicircle: ElementFactory = () => ({
|
||||||
expression: `filters
|
expression: `filters
|
||||||
| demodata
|
| demodata
|
||||||
| math "mean(percent_uptime)"
|
| math "mean(percent_uptime)"
|
||||||
| progress shape="semicircle" label={formatnumber 0%} font={font size=24 family="${
|
| progress shape="semicircle" label={formatnumber 0%} font={font size=24 family="${openSans.value}" color="#000000" align=center}
|
||||||
openSans.value
|
|
||||||
}" color="#000000" align=center}
|
|
||||||
| render`,
|
| render`,
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,8 +19,6 @@ export const progressWheel: ElementFactory = () => ({
|
||||||
expression: `filters
|
expression: `filters
|
||||||
| demodata
|
| demodata
|
||||||
| math "mean(percent_uptime)"
|
| math "mean(percent_uptime)"
|
||||||
| progress shape="wheel" label={formatnumber 0%} font={font size=24 family="${
|
| progress shape="wheel" label={formatnumber 0%} font={font size=24 family="${openSans.value}" color="#000000" align=center}
|
||||||
openSans.value
|
|
||||||
}" color="#000000" align=center}
|
|
||||||
| render`,
|
| render`,
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,8 +19,6 @@ export const verticalProgressBar: ElementFactory = () => ({
|
||||||
expression: `filters
|
expression: `filters
|
||||||
| demodata
|
| demodata
|
||||||
| math "mean(percent_uptime)"
|
| math "mean(percent_uptime)"
|
||||||
| progress shape="verticalBar" label={formatnumber 0%} font={font size=24 family="${
|
| progress shape="verticalBar" label={formatnumber 0%} font={font size=24 family="${openSans.value}" color="#000000" align=center}
|
||||||
openSans.value
|
|
||||||
}" color="#000000" align=center}
|
|
||||||
| render`,
|
| render`,
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,8 +19,6 @@ export const verticalProgressPill: ElementFactory = () => ({
|
||||||
expression: `filters
|
expression: `filters
|
||||||
| demodata
|
| demodata
|
||||||
| math "mean(percent_uptime)"
|
| math "mean(percent_uptime)"
|
||||||
| progress shape="verticalPill" label={formatnumber 0%} font={font size=24 family="${
|
| progress shape="verticalPill" label={formatnumber 0%} font={font size=24 family="${openSans.value}" color="#000000" align=center}
|
||||||
openSans.value
|
|
||||||
}" color="#000000" align=center}
|
|
||||||
| render`,
|
| render`,
|
||||||
});
|
});
|
||||||
|
|
|
@ -38,9 +38,7 @@ export function metric(): ExpressionFunction<'metric', Context, Arguments, Rende
|
||||||
metricFont: {
|
metricFont: {
|
||||||
types: ['style'],
|
types: ['style'],
|
||||||
help: argHelp.metricFont,
|
help: argHelp.metricFont,
|
||||||
default: `{font size=48 family="${
|
default: `{font size=48 family="${openSans.value}" color="#000000" align=center lHeight=48}`,
|
||||||
openSans.value
|
|
||||||
}" color="#000000" align=center lHeight=48}`,
|
|
||||||
},
|
},
|
||||||
labelFont: {
|
labelFont: {
|
||||||
types: ['style'],
|
types: ['style'],
|
||||||
|
|
|
@ -126,7 +126,7 @@ export const withUnconnectedElementsLoadedTelemetry = function<P extends object>
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return <Component {...other as P} workpad={workpad} />;
|
return <Component {...(other as P)} workpad={workpad} />;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ interface WithActionId {
|
||||||
// reselect-based data flow
|
// reselect-based data flow
|
||||||
export type PlainFun = (...args: Json[]) => Json;
|
export type PlainFun = (...args: Json[]) => Json;
|
||||||
export type Selector = (...fns: Resolve[]) => Resolve;
|
export type Selector = (...fns: Resolve[]) => Resolve;
|
||||||
export type Resolve = ((obj: State) => Json);
|
export type Resolve = (obj: State) => Json;
|
||||||
|
|
||||||
export type TypeName = string;
|
export type TypeName = string;
|
||||||
export type Payload = JsonMap;
|
export type Payload = JsonMap;
|
||||||
|
|
|
@ -39,9 +39,7 @@ export const queryEsSQL = (elasticsearchClient, { count, query, filter, timezone
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
if (e.message.indexOf('parsing_exception') > -1) {
|
if (e.message.indexOf('parsing_exception') > -1) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Couldn't parse Elasticsearch SQL query. You may need to add double quotes to names containing special characters. Check your query and try again. Error: ${
|
`Couldn't parse Elasticsearch SQL query. You may need to add double quotes to names containing special characters. Check your query and try again. Error: ${e.message}`
|
||||||
e.message
|
|
||||||
}`
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
throw new Error(`Unexpected error from Elasticsearch: ${e.message}`);
|
throw new Error(`Unexpected error from Elasticsearch: ${e.message}`);
|
||||||
|
|
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