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