mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[7.x] Upgrade Prettier 1.19 (#50506)
* Upgrade Prettier to 1.19 * Fix all prettier issues
This commit is contained in:
parent
b601b692ac
commit
b08dc0c8b4
279 changed files with 1857 additions and 1998 deletions
|
@ -427,7 +427,7 @@
|
|||
"pngjs": "^3.4.0",
|
||||
"postcss": "^7.0.5",
|
||||
"postcss-url": "^8.0.0",
|
||||
"prettier": "^1.18.2",
|
||||
"prettier": "^1.19.1",
|
||||
"proxyquire": "1.8.0",
|
||||
"regenerate": "^1.4.0",
|
||||
"sass-lint": "^1.12.1",
|
||||
|
|
|
@ -29,10 +29,7 @@ import { first, ignoreElements, mergeMap } from 'rxjs/operators';
|
|||
*/
|
||||
export function observeReadable(readable: Readable): Rx.Observable<never> {
|
||||
return Rx.race(
|
||||
Rx.fromEvent(readable, 'end').pipe(
|
||||
first(),
|
||||
ignoreElements()
|
||||
),
|
||||
Rx.fromEvent(readable, 'end').pipe(first(), ignoreElements()),
|
||||
|
||||
Rx.fromEvent(readable, 'error').pipe(
|
||||
first(),
|
||||
|
|
|
@ -112,10 +112,7 @@ describe('#getWritten$()', () => {
|
|||
const done$ = new Rx.Subject();
|
||||
const promise = log
|
||||
.getWritten$()
|
||||
.pipe(
|
||||
takeUntil(done$),
|
||||
toArray()
|
||||
)
|
||||
.pipe(takeUntil(done$), toArray())
|
||||
.toPromise();
|
||||
|
||||
log.debug('foo');
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
"log-symbols": "^2.2.0",
|
||||
"ncp": "^2.0.0",
|
||||
"ora": "^1.4.0",
|
||||
"prettier": "^1.18.2",
|
||||
"prettier": "^1.19.1",
|
||||
"read-pkg": "^5.2.0",
|
||||
"rxjs": "^6.5.3",
|
||||
"spawn-sync": "^1.0.15",
|
||||
|
|
|
@ -101,7 +101,12 @@ test('handles dependencies of dependencies', async () => {
|
|||
'packages/baz'
|
||||
);
|
||||
|
||||
const projects = new Map([['kibana', kibana], ['foo', foo], ['bar', bar], ['baz', baz]]);
|
||||
const projects = new Map([
|
||||
['kibana', kibana],
|
||||
['foo', foo],
|
||||
['bar', bar],
|
||||
['baz', baz],
|
||||
]);
|
||||
const projectGraph = buildProjectGraph(projects);
|
||||
|
||||
const logMock = jest.spyOn(console, 'log').mockImplementation(noop);
|
||||
|
@ -133,7 +138,10 @@ test('does not run installer if no deps in package', async () => {
|
|||
'packages/bar'
|
||||
);
|
||||
|
||||
const projects = new Map([['kibana', kibana], ['bar', bar]]);
|
||||
const projects = new Map([
|
||||
['kibana', kibana],
|
||||
['bar', bar],
|
||||
]);
|
||||
const projectGraph = buildProjectGraph(projects);
|
||||
|
||||
const logMock = jest.spyOn(console, 'log').mockImplementation(noop);
|
||||
|
@ -193,7 +201,10 @@ test('calls "kbn:bootstrap" scripts and links executables after installing deps'
|
|||
'packages/bar'
|
||||
);
|
||||
|
||||
const projects = new Map([['kibana', kibana], ['bar', bar]]);
|
||||
const projects = new Map([
|
||||
['kibana', kibana],
|
||||
['bar', bar],
|
||||
]);
|
||||
const projectGraph = buildProjectGraph(projects);
|
||||
|
||||
jest.spyOn(console, 'log').mockImplementation(noop);
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
"homepage": "https://github.com/jbudz/spec-to-console#readme",
|
||||
"devDependencies": {
|
||||
"jest": "^24.9.0",
|
||||
"prettier": "^1.18.2"
|
||||
"prettier": "^1.19.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": "^2.11.0",
|
||||
|
|
|
@ -130,10 +130,7 @@ export class NavLinksService {
|
|||
|
||||
return {
|
||||
getNavLinks$: () => {
|
||||
return navLinks$.pipe(
|
||||
map(sortNavLinks),
|
||||
takeUntil(this.stop$)
|
||||
);
|
||||
return navLinks$.pipe(map(sortNavLinks), takeUntil(this.stop$));
|
||||
},
|
||||
|
||||
get(id: string) {
|
||||
|
@ -192,7 +189,10 @@ export class NavLinksService {
|
|||
}
|
||||
|
||||
function sortNavLinks(navLinks: ReadonlyMap<string, NavLinkWrapper>) {
|
||||
return sortBy([...navLinks.values()].map(link => link.properties), 'order');
|
||||
return sortBy(
|
||||
[...navLinks.values()].map(link => link.properties),
|
||||
'order'
|
||||
);
|
||||
}
|
||||
|
||||
function relativeToAbsolute(url: string) {
|
||||
|
|
|
@ -106,10 +106,7 @@ describe('RecentlyAccessed#start()', () => {
|
|||
const stop$ = new Subject();
|
||||
const observedValues$ = recentlyAccessed
|
||||
.get$()
|
||||
.pipe(
|
||||
bufferCount(3),
|
||||
takeUntil(stop$)
|
||||
)
|
||||
.pipe(bufferCount(3), takeUntil(stop$))
|
||||
.toPromise();
|
||||
recentlyAccessed.add('/app/item1', 'Item 1', 'item1');
|
||||
recentlyAccessed.add('/app/item2', 'Item 2', 'item2');
|
||||
|
|
|
@ -174,7 +174,10 @@ describe('#setup()', () => {
|
|||
it('injects legacy dependency to context#setup()', async () => {
|
||||
const pluginA = Symbol();
|
||||
const pluginB = Symbol();
|
||||
const pluginDependencies = new Map<symbol, symbol[]>([[pluginA, []], [pluginB, [pluginA]]]);
|
||||
const pluginDependencies = new Map<symbol, symbol[]>([
|
||||
[pluginA, []],
|
||||
[pluginB, [pluginA]],
|
||||
]);
|
||||
MockPluginsService.getOpaqueIds.mockReturnValue(pluginDependencies);
|
||||
await setupCore();
|
||||
|
||||
|
|
|
@ -68,18 +68,27 @@ describe('setup.getPlugins()', () => {
|
|||
it('returns injectedMetadata.uiPlugins', () => {
|
||||
const injectedMetadata = new InjectedMetadataService({
|
||||
injectedMetadata: {
|
||||
uiPlugins: [{ id: 'plugin-1', plugin: {} }, { id: 'plugin-2', plugin: {} }],
|
||||
uiPlugins: [
|
||||
{ id: 'plugin-1', plugin: {} },
|
||||
{ id: 'plugin-2', plugin: {} },
|
||||
],
|
||||
},
|
||||
} as any);
|
||||
|
||||
const plugins = injectedMetadata.setup().getPlugins();
|
||||
expect(plugins).toEqual([{ id: 'plugin-1', plugin: {} }, { id: 'plugin-2', plugin: {} }]);
|
||||
expect(plugins).toEqual([
|
||||
{ id: 'plugin-1', plugin: {} },
|
||||
{ id: 'plugin-2', plugin: {} },
|
||||
]);
|
||||
});
|
||||
|
||||
it('returns frozen version of uiPlugins', () => {
|
||||
const injectedMetadata = new InjectedMetadataService({
|
||||
injectedMetadata: {
|
||||
uiPlugins: [{ id: 'plugin-1', plugin: {} }, { id: 'plugin-2', plugin: {} }],
|
||||
uiPlugins: [
|
||||
{ id: 'plugin-1', plugin: {} },
|
||||
{ id: 'plugin-2', plugin: {} },
|
||||
],
|
||||
},
|
||||
} as any);
|
||||
|
||||
|
|
|
@ -42,7 +42,10 @@ describe('PriorityMap', () => {
|
|||
map = map.add('b', { priority: 3 });
|
||||
map = map.add('c', { priority: 2 });
|
||||
map = map.remove('c');
|
||||
expect([...map]).toEqual([['b', { priority: 3 }], ['a', { priority: 1 }]]);
|
||||
expect([...map]).toEqual([
|
||||
['b', { priority: 3 }],
|
||||
['a', { priority: 1 }],
|
||||
]);
|
||||
});
|
||||
|
||||
it('adds duplicate priorities to end', () => {
|
||||
|
|
|
@ -223,10 +223,13 @@ test('`PluginsService.setup` exposes dependent setup contracts to plugins', asyn
|
|||
|
||||
test('`PluginsService.setup` does not set missing dependent setup contracts', async () => {
|
||||
plugins = [{ id: 'pluginD', plugin: createManifest('pluginD', { optional: ['missing'] }) }];
|
||||
mockPluginInitializers.set('pluginD', jest.fn(() => ({
|
||||
setup: jest.fn(),
|
||||
start: jest.fn(),
|
||||
})) as any);
|
||||
mockPluginInitializers.set(
|
||||
'pluginD',
|
||||
jest.fn(() => ({
|
||||
setup: jest.fn(),
|
||||
start: jest.fn(),
|
||||
})) as any
|
||||
);
|
||||
|
||||
const pluginsService = new PluginsService(mockCoreContext, plugins);
|
||||
await pluginsService.setup(mockSetupDeps);
|
||||
|
@ -268,10 +271,13 @@ test('`PluginsService.start` exposes dependent start contracts to plugins', asyn
|
|||
|
||||
test('`PluginsService.start` does not set missing dependent start contracts', async () => {
|
||||
plugins = [{ id: 'pluginD', plugin: createManifest('pluginD', { optional: ['missing'] }) }];
|
||||
mockPluginInitializers.set('pluginD', jest.fn(() => ({
|
||||
setup: jest.fn(),
|
||||
start: jest.fn(),
|
||||
})) as any);
|
||||
mockPluginInitializers.set(
|
||||
'pluginD',
|
||||
jest.fn(() => ({
|
||||
setup: jest.fn(),
|
||||
start: jest.fn(),
|
||||
})) as any
|
||||
);
|
||||
|
||||
const pluginsService = new PluginsService(mockCoreContext, plugins);
|
||||
await pluginsService.setup(mockSetupDeps);
|
||||
|
|
|
@ -183,10 +183,7 @@ describe('#getLoadingCount$()', () => {
|
|||
const done$ = new Rx.Subject();
|
||||
const promise = uiSettingsApi
|
||||
.getLoadingCount$()
|
||||
.pipe(
|
||||
takeUntil(done$),
|
||||
toArray()
|
||||
)
|
||||
.pipe(takeUntil(done$), toArray())
|
||||
.toPromise();
|
||||
|
||||
await uiSettingsApi.batchSet('foo', 'bar');
|
||||
|
@ -214,10 +211,7 @@ describe('#getLoadingCount$()', () => {
|
|||
const done$ = new Rx.Subject();
|
||||
const promise = uiSettingsApi
|
||||
.getLoadingCount$()
|
||||
.pipe(
|
||||
takeUntil(done$),
|
||||
toArray()
|
||||
)
|
||||
.pipe(takeUntil(done$), toArray())
|
||||
.toPromise();
|
||||
|
||||
await uiSettingsApi.batchSet('foo', 'bar');
|
||||
|
@ -250,7 +244,10 @@ describe('#stop', () => {
|
|||
uiSettingsApi.stop();
|
||||
|
||||
// both observables should emit the same values, and complete before the request is done loading
|
||||
await expect(promise).resolves.toEqual([[0, 1], [0, 1]]);
|
||||
await expect(promise).resolves.toEqual([
|
||||
[0, 1],
|
||||
[0, 1],
|
||||
]);
|
||||
await batchSetPromise;
|
||||
});
|
||||
});
|
||||
|
|
|
@ -83,10 +83,7 @@ describe('#get$', () => {
|
|||
const { config } = setup();
|
||||
const values = await config
|
||||
.get$('dateFormat')
|
||||
.pipe(
|
||||
take(1),
|
||||
toArray()
|
||||
)
|
||||
.pipe(take(1), toArray())
|
||||
.toPromise();
|
||||
|
||||
expect(values).toEqual(['Browser']);
|
||||
|
@ -122,10 +119,7 @@ You can use \`config.get("unknown key", defaultValue)\`, which will just return
|
|||
|
||||
const values = await config
|
||||
.get$('dateFormat')
|
||||
.pipe(
|
||||
take(2),
|
||||
toArray()
|
||||
)
|
||||
.pipe(take(2), toArray())
|
||||
.toPromise();
|
||||
|
||||
expect(values).toEqual(['Browser', 'new format']);
|
||||
|
@ -144,10 +138,7 @@ You can use \`config.get("unknown key", defaultValue)\`, which will just return
|
|||
|
||||
const values = await config
|
||||
.get$('dateFormat', 'my default')
|
||||
.pipe(
|
||||
take(3),
|
||||
toArray()
|
||||
)
|
||||
.pipe(take(3), toArray())
|
||||
.toPromise();
|
||||
|
||||
expect(values).toEqual(['my default', 'new format', 'my default']);
|
||||
|
|
|
@ -153,10 +153,7 @@ Array [
|
|||
});
|
||||
|
||||
it('resubscribes if parent completes', async () => {
|
||||
const shared = counter().pipe(
|
||||
take(4),
|
||||
shareWeakReplay(4)
|
||||
);
|
||||
const shared = counter().pipe(take(4), shareWeakReplay(4));
|
||||
|
||||
await expect(Promise.all([record(shared.pipe(take(1))), record(shared)])).resolves
|
||||
.toMatchInlineSnapshot(`
|
||||
|
@ -199,10 +196,7 @@ Array [
|
|||
it('supports parents that complete synchronously', async () => {
|
||||
const next = jest.fn();
|
||||
const complete = jest.fn();
|
||||
const shared = counter({ async: false }).pipe(
|
||||
take(3),
|
||||
shareWeakReplay(1)
|
||||
);
|
||||
const shared = counter({ async: false }).pipe(take(3), shareWeakReplay(1));
|
||||
|
||||
shared.subscribe({ next, complete });
|
||||
expect(next.mock.calls).toMatchInlineSnapshot(`
|
||||
|
|
|
@ -34,19 +34,16 @@ export function ensureDeepObject(obj: any): any {
|
|||
return obj.map(item => ensureDeepObject(item));
|
||||
}
|
||||
|
||||
return Object.keys(obj).reduce(
|
||||
(fullObject, propertyKey) => {
|
||||
const propertyValue = obj[propertyKey];
|
||||
if (!propertyKey.includes(separator)) {
|
||||
fullObject[propertyKey] = ensureDeepObject(propertyValue);
|
||||
} else {
|
||||
walk(fullObject, propertyKey.split(separator), propertyValue);
|
||||
}
|
||||
return Object.keys(obj).reduce((fullObject, propertyKey) => {
|
||||
const propertyValue = obj[propertyKey];
|
||||
if (!propertyKey.includes(separator)) {
|
||||
fullObject[propertyKey] = ensureDeepObject(propertyValue);
|
||||
} else {
|
||||
walk(fullObject, propertyKey.split(separator), propertyValue);
|
||||
}
|
||||
|
||||
return fullObject;
|
||||
},
|
||||
{} as any
|
||||
);
|
||||
return fullObject;
|
||||
}, {} as any);
|
||||
}
|
||||
|
||||
function walk(obj: any, keys: string[], value: any) {
|
||||
|
|
|
@ -77,18 +77,15 @@ export class PluginsSystem {
|
|||
|
||||
this.log.debug(`Setting up plugin "${pluginName}"...`);
|
||||
const pluginDeps = new Set([...plugin.requiredPlugins, ...plugin.optionalPlugins]);
|
||||
const pluginDepContracts = Array.from(pluginDeps).reduce(
|
||||
(depContracts, dependencyName) => {
|
||||
// Only set if present. Could be absent if plugin does not have server-side code or is a
|
||||
// missing optional dependency.
|
||||
if (contracts.has(dependencyName)) {
|
||||
depContracts[dependencyName] = contracts.get(dependencyName);
|
||||
}
|
||||
const pluginDepContracts = Array.from(pluginDeps).reduce((depContracts, dependencyName) => {
|
||||
// Only set if present. Could be absent if plugin does not have server-side code or is a
|
||||
// missing optional dependency.
|
||||
if (contracts.has(dependencyName)) {
|
||||
depContracts[dependencyName] = contracts.get(dependencyName);
|
||||
}
|
||||
|
||||
return depContracts;
|
||||
},
|
||||
{} as Record<PluginName, unknown>
|
||||
);
|
||||
return depContracts;
|
||||
}, {} as Record<PluginName, unknown>);
|
||||
|
||||
contracts.set(
|
||||
pluginName,
|
||||
|
@ -116,18 +113,15 @@ export class PluginsSystem {
|
|||
this.log.debug(`Starting plugin "${pluginName}"...`);
|
||||
const plugin = this.plugins.get(pluginName)!;
|
||||
const pluginDeps = new Set([...plugin.requiredPlugins, ...plugin.optionalPlugins]);
|
||||
const pluginDepContracts = Array.from(pluginDeps).reduce(
|
||||
(depContracts, dependencyName) => {
|
||||
// Only set if present. Could be absent if plugin does not have server-side code or is a
|
||||
// missing optional dependency.
|
||||
if (contracts.has(dependencyName)) {
|
||||
depContracts[dependencyName] = contracts.get(dependencyName);
|
||||
}
|
||||
const pluginDepContracts = Array.from(pluginDeps).reduce((depContracts, dependencyName) => {
|
||||
// Only set if present. Could be absent if plugin does not have server-side code or is a
|
||||
// missing optional dependency.
|
||||
if (contracts.has(dependencyName)) {
|
||||
depContracts[dependencyName] = contracts.get(dependencyName);
|
||||
}
|
||||
|
||||
return depContracts;
|
||||
},
|
||||
{} as Record<PluginName, unknown>
|
||||
);
|
||||
return depContracts;
|
||||
}, {} as Record<PluginName, unknown>);
|
||||
|
||||
contracts.set(
|
||||
pluginName,
|
||||
|
|
|
@ -39,17 +39,14 @@ const blacklist = ['migrationVersion', 'references'];
|
|||
|
||||
export function getRootPropertiesObjects(mappings: IndexMapping) {
|
||||
const rootProperties = getRootProperties(mappings);
|
||||
return Object.entries(rootProperties).reduce(
|
||||
(acc, [key, value]) => {
|
||||
// we consider the existence of the properties or type of object to designate that this is an object datatype
|
||||
if (
|
||||
!blacklist.includes(key) &&
|
||||
((value as ComplexFieldMapping).properties || value.type === 'object')
|
||||
) {
|
||||
acc[key] = value;
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{} as MappingProperties
|
||||
);
|
||||
return Object.entries(rootProperties).reduce((acc, [key, value]) => {
|
||||
// we consider the existence of the properties or type of object to designate that this is an object datatype
|
||||
if (
|
||||
!blacklist.includes(key) &&
|
||||
((value as ComplexFieldMapping).properties || value.type === 'object')
|
||||
) {
|
||||
acc[key] = value;
|
||||
}
|
||||
return acc;
|
||||
}, {} as MappingProperties);
|
||||
}
|
||||
|
|
|
@ -246,15 +246,17 @@ export class SavedObjectsRepository {
|
|||
const expectedResult = {
|
||||
esRequestIndex: requestIndexCounter++,
|
||||
requestedId: object.id,
|
||||
rawMigratedDoc: this._serializer.savedObjectToRaw(this._migrator.migrateDocument({
|
||||
id: object.id,
|
||||
type: object.type,
|
||||
attributes: object.attributes,
|
||||
migrationVersion: object.migrationVersion,
|
||||
namespace,
|
||||
updated_at: time,
|
||||
references: object.references || [],
|
||||
}) as SanitizedSavedObjectDoc),
|
||||
rawMigratedDoc: this._serializer.savedObjectToRaw(
|
||||
this._migrator.migrateDocument({
|
||||
id: object.id,
|
||||
type: object.type,
|
||||
attributes: object.attributes,
|
||||
migrationVersion: object.migrationVersion,
|
||||
namespace,
|
||||
updated_at: time,
|
||||
references: object.references || [],
|
||||
}) as SanitizedSavedObjectDoc
|
||||
),
|
||||
};
|
||||
|
||||
bulkCreateParams.push(
|
||||
|
|
|
@ -70,7 +70,10 @@ test('injects legacy dependency to context#setup()', async () => {
|
|||
|
||||
const pluginA = Symbol();
|
||||
const pluginB = Symbol();
|
||||
const pluginDependencies = new Map<symbol, symbol[]>([[pluginA, []], [pluginB, [pluginA]]]);
|
||||
const pluginDependencies = new Map<symbol, symbol[]>([
|
||||
[pluginA, []],
|
||||
[pluginB, [pluginA]],
|
||||
]);
|
||||
mockPluginsService.discover.mockResolvedValue(pluginDependencies);
|
||||
|
||||
await server.setup();
|
||||
|
|
|
@ -83,14 +83,11 @@ export class UiSettingsClient implements IUiSettingsClient {
|
|||
async getAll<T extends SavedObjectAttribute = any>() {
|
||||
const raw = await this.getRaw();
|
||||
|
||||
return Object.keys(raw).reduce(
|
||||
(all, key) => {
|
||||
const item = raw[key];
|
||||
all[key] = ('userValue' in item ? item.userValue : item.value) as T;
|
||||
return all;
|
||||
},
|
||||
{} as Record<string, T>
|
||||
);
|
||||
return Object.keys(raw).reduce((all, key) => {
|
||||
const item = raw[key];
|
||||
all[key] = ('userValue' in item ? item.userValue : item.value) as T;
|
||||
return all;
|
||||
}, {} as Record<string, T>);
|
||||
}
|
||||
|
||||
async getUserProvided<T extends SavedObjectAttribute = any>(): Promise<UserProvided<T>> {
|
||||
|
|
|
@ -254,23 +254,20 @@ export class ContextContainer<THandler extends HandlerFunction<any>>
|
|||
return [...this.contextProviders]
|
||||
.sort(sortByCoreFirst(this.coreId))
|
||||
.filter(([contextName]) => contextsToBuild.has(contextName))
|
||||
.reduce(
|
||||
async (contextPromise, [contextName, { provider, source: providerSource }]) => {
|
||||
const resolvedContext = await contextPromise;
|
||||
.reduce(async (contextPromise, [contextName, { provider, source: providerSource }]) => {
|
||||
const resolvedContext = await contextPromise;
|
||||
|
||||
// For the next provider, only expose the context available based on the dependencies of the plugin that
|
||||
// registered that provider.
|
||||
const exposedContext = pick(resolvedContext, [
|
||||
...this.getContextNamesForSource(providerSource),
|
||||
]) as Partial<HandlerContextType<THandler>>;
|
||||
// For the next provider, only expose the context available based on the dependencies of the plugin that
|
||||
// registered that provider.
|
||||
const exposedContext = pick(resolvedContext, [
|
||||
...this.getContextNamesForSource(providerSource),
|
||||
]) as Partial<HandlerContextType<THandler>>;
|
||||
|
||||
return {
|
||||
...resolvedContext,
|
||||
[contextName]: await provider(exposedContext, ...contextArgs),
|
||||
};
|
||||
},
|
||||
Promise.resolve({}) as Promise<HandlerContextType<THandler>>
|
||||
);
|
||||
return {
|
||||
...resolvedContext,
|
||||
[contextName]: await provider(exposedContext, ...contextArgs),
|
||||
};
|
||||
}, Promise.resolve({}) as Promise<HandlerContextType<THandler>>);
|
||||
}
|
||||
|
||||
private getContextNamesForSource(
|
||||
|
|
|
@ -42,7 +42,11 @@ describe('groupIntoMap', () => {
|
|||
const groupBy = (item: { id: number }) => item.id;
|
||||
|
||||
expect(groupIntoMap([{ id: 1 }, { id: 2 }, { id: 3 }], groupBy)).toEqual(
|
||||
new Map([[1, [{ id: 1 }]], [2, [{ id: 2 }]], [3, [{ id: 3 }]]])
|
||||
new Map([
|
||||
[1, [{ id: 1 }]],
|
||||
[2, [{ id: 2 }]],
|
||||
[3, [{ id: 3 }]],
|
||||
])
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -93,7 +97,12 @@ describe('mapValuesOfMap', () => {
|
|||
map.set(even, 2);
|
||||
map.set(odd, 1);
|
||||
|
||||
expect(mapValuesOfMap(map, mapper)).toEqual(new Map([[even, 6], [odd, 3]]));
|
||||
expect(mapValuesOfMap(map, mapper)).toEqual(
|
||||
new Map([
|
||||
[even, 6],
|
||||
[odd, 3],
|
||||
])
|
||||
);
|
||||
expect(map.get(odd)).toEqual(1);
|
||||
expect(map.get(even)).toEqual(2);
|
||||
});
|
||||
|
|
|
@ -66,20 +66,17 @@ const mergeObjects = <T extends Record<string, any>, U extends Record<string, an
|
|||
baseObj: T,
|
||||
overrideObj: U
|
||||
): T & U =>
|
||||
[...new Set([...Object.keys(baseObj), ...Object.keys(overrideObj)])].reduce(
|
||||
(merged, key) => {
|
||||
const baseVal = baseObj[key];
|
||||
const overrideVal = overrideObj[key];
|
||||
[...new Set([...Object.keys(baseObj), ...Object.keys(overrideObj)])].reduce((merged, key) => {
|
||||
const baseVal = baseObj[key];
|
||||
const overrideVal = overrideObj[key];
|
||||
|
||||
if (isMergable(baseVal) && isMergable(overrideVal)) {
|
||||
merged[key] = mergeObjects(baseVal, overrideVal);
|
||||
} else if (overrideVal !== undefined) {
|
||||
merged[key] = overrideVal;
|
||||
} else if (baseVal !== undefined) {
|
||||
merged[key] = baseVal;
|
||||
}
|
||||
if (isMergable(baseVal) && isMergable(overrideVal)) {
|
||||
merged[key] = mergeObjects(baseVal, overrideVal);
|
||||
} else if (overrideVal !== undefined) {
|
||||
merged[key] = overrideVal;
|
||||
} else if (baseVal !== undefined) {
|
||||
merged[key] = baseVal;
|
||||
}
|
||||
|
||||
return merged;
|
||||
},
|
||||
{} as any
|
||||
);
|
||||
return merged;
|
||||
}, {} as any);
|
||||
|
|
|
@ -18,14 +18,11 @@
|
|||
*/
|
||||
|
||||
export function pick<T extends object, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> {
|
||||
return keys.reduce(
|
||||
(acc, key) => {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
acc[key] = obj[key];
|
||||
}
|
||||
return keys.reduce((acc, key) => {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
acc[key] = obj[key];
|
||||
}
|
||||
|
||||
return acc;
|
||||
},
|
||||
{} as Pick<T, K>
|
||||
);
|
||||
return acc;
|
||||
}, {} as Pick<T, K>);
|
||||
}
|
||||
|
|
|
@ -36,24 +36,21 @@ interface Options {
|
|||
* violations or returns undefined.
|
||||
*/
|
||||
export function assertLicensesValid({ packages, validLicenses }: Options) {
|
||||
const invalidMsgs = packages.reduce(
|
||||
(acc, pkg) => {
|
||||
const invalidLicenses = pkg.licenses.filter(license => !validLicenses.includes(license));
|
||||
const invalidMsgs = packages.reduce((acc, pkg) => {
|
||||
const invalidLicenses = pkg.licenses.filter(license => !validLicenses.includes(license));
|
||||
|
||||
if (pkg.licenses.length && !invalidLicenses.length) {
|
||||
return acc;
|
||||
}
|
||||
if (pkg.licenses.length && !invalidLicenses.length) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
return acc.concat(dedent`
|
||||
return acc.concat(dedent`
|
||||
${pkg.name}
|
||||
version: ${pkg.version}
|
||||
all licenses: ${pkg.licenses}
|
||||
invalid licenses: ${invalidLicenses.join(', ')}
|
||||
path: ${pkg.relative}
|
||||
`);
|
||||
},
|
||||
[] as string[]
|
||||
);
|
||||
}, [] as string[]);
|
||||
|
||||
if (invalidMsgs.length) {
|
||||
throw createFailError(
|
||||
|
|
|
@ -52,11 +52,13 @@ export class IndexPatterns {
|
|||
}
|
||||
|
||||
private async refreshSavedObjectsCache() {
|
||||
this.savedObjectsCache = (await this.savedObjectsClient.find({
|
||||
type: 'index-pattern',
|
||||
fields: [],
|
||||
perPage: 10000,
|
||||
})).savedObjects;
|
||||
this.savedObjectsCache = (
|
||||
await this.savedObjectsClient.find({
|
||||
type: 'index-pattern',
|
||||
fields: [],
|
||||
perPage: 10000,
|
||||
})
|
||||
).savedObjects;
|
||||
}
|
||||
|
||||
getIds = async (refresh: boolean = false) => {
|
||||
|
|
|
@ -83,9 +83,11 @@ function MetricsAxisOptions(props: ValidationVisOptionsProps<BasicVislibParams>)
|
|||
// stores previous aggs' custom labels
|
||||
const [lastCustomLabels, setLastCustomLabels] = useState({} as { [key: string]: string });
|
||||
// stores previous aggs' field and type
|
||||
const [lastSeriesAgg, setLastSeriesAgg] = useState({} as {
|
||||
[key: string]: { type: string; field: string };
|
||||
});
|
||||
const [lastSeriesAgg, setLastSeriesAgg] = useState(
|
||||
{} as {
|
||||
[key: string]: { type: string; field: string };
|
||||
}
|
||||
);
|
||||
|
||||
const updateAxisTitle = () => {
|
||||
const axes = cloneDeep(stateParams.valueAxes);
|
||||
|
|
|
@ -62,7 +62,10 @@ describe('extractExportDetails', () => {
|
|||
[
|
||||
[
|
||||
objLine('1', 'index-pattern'),
|
||||
detailsLine(1, [{ id: '2', type: 'index-pattern' }, { id: '3', type: 'index-pattern' }]),
|
||||
detailsLine(1, [
|
||||
{ id: '2', type: 'index-pattern' },
|
||||
{ id: '3', type: 'index-pattern' },
|
||||
]),
|
||||
].join(''),
|
||||
],
|
||||
{
|
||||
|
@ -75,7 +78,10 @@ describe('extractExportDetails', () => {
|
|||
expect(result).toEqual({
|
||||
exportedCount: 1,
|
||||
missingRefCount: 2,
|
||||
missingReferences: [{ id: '2', type: 'index-pattern' }, { id: '3', type: 'index-pattern' }],
|
||||
missingReferences: [
|
||||
{ id: '2', type: 'index-pattern' },
|
||||
{ id: '3', type: 'index-pattern' },
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -82,7 +82,10 @@ function RegionMapOptions(props: RegionMapOptionsProps) {
|
|||
const setField = useCallback(
|
||||
(paramName: 'selectedJoinField', value: FileLayerField['name']) => {
|
||||
if (stateParams.selectedLayer) {
|
||||
setValue(paramName, stateParams.selectedLayer.fields.find(f => f.name === value));
|
||||
setValue(
|
||||
paramName,
|
||||
stateParams.selectedLayer.fields.find(f => f.name === value)
|
||||
);
|
||||
}
|
||||
},
|
||||
[setValue, stateParams.selectedLayer]
|
||||
|
|
|
@ -42,19 +42,16 @@ export function ensureDeepObject(obj: any): any {
|
|||
return obj.map(item => ensureDeepObject(item));
|
||||
}
|
||||
|
||||
return Object.keys(obj).reduce(
|
||||
(fullObject, propertyKey) => {
|
||||
const propertyValue = obj[propertyKey];
|
||||
if (!propertyKey.includes(separator)) {
|
||||
fullObject[propertyKey] = ensureDeepObject(propertyValue);
|
||||
} else {
|
||||
walk(fullObject, propertyKey.split(separator), propertyValue);
|
||||
}
|
||||
return Object.keys(obj).reduce((fullObject, propertyKey) => {
|
||||
const propertyValue = obj[propertyKey];
|
||||
if (!propertyKey.includes(separator)) {
|
||||
fullObject[propertyKey] = ensureDeepObject(propertyValue);
|
||||
} else {
|
||||
walk(fullObject, propertyKey.split(separator), propertyValue);
|
||||
}
|
||||
|
||||
return fullObject;
|
||||
},
|
||||
{} as any
|
||||
);
|
||||
return fullObject;
|
||||
}, {} as any);
|
||||
}
|
||||
|
||||
function walk(obj: any, keys: string[], value: any) {
|
||||
|
|
|
@ -253,13 +253,10 @@ export class AggConfigs {
|
|||
// collect all the aggregations
|
||||
const aggregations = this.aggs
|
||||
.filter(agg => agg.enabled && agg.type)
|
||||
.reduce(
|
||||
(requestValuesAggs, agg: AggConfig) => {
|
||||
const aggs = agg.getRequestAggs();
|
||||
return aggs ? requestValuesAggs.concat(aggs) : requestValuesAggs;
|
||||
},
|
||||
[] as AggConfig[]
|
||||
);
|
||||
.reduce((requestValuesAggs, agg: AggConfig) => {
|
||||
const aggs = agg.getRequestAggs();
|
||||
return aggs ? requestValuesAggs.concat(aggs) : requestValuesAggs;
|
||||
}, [] as AggConfig[]);
|
||||
// move metrics to the end
|
||||
return _.sortBy(aggregations, (agg: AggConfig) =>
|
||||
agg.type.type === AggGroupNames.Metrics ? 1 : 0
|
||||
|
@ -282,13 +279,10 @@ export class AggConfigs {
|
|||
* @return {array[AggConfig]}
|
||||
*/
|
||||
getResponseAggs(): AggConfig[] {
|
||||
return this.getRequestAggs().reduce(
|
||||
function(responseValuesAggs, agg: AggConfig) {
|
||||
const aggs = agg.getResponseAggs();
|
||||
return aggs ? responseValuesAggs.concat(aggs) : responseValuesAggs;
|
||||
},
|
||||
[] as AggConfig[]
|
||||
);
|
||||
return this.getRequestAggs().reduce(function(responseValuesAggs, agg: AggConfig) {
|
||||
const aggs = agg.getResponseAggs();
|
||||
return aggs ? responseValuesAggs.concat(aggs) : responseValuesAggs;
|
||||
}, [] as AggConfig[]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -156,8 +156,9 @@ describe('Geohash Agg', () => {
|
|||
describe('aggregation options', () => {
|
||||
it('should only create geohash_grid and geo_centroid aggregations when isFilteredByCollar is false', () => {
|
||||
const aggConfigs = getAggConfigs({ isFilteredByCollar: false });
|
||||
const requestAggs = geoHashBucketAgg.getRequestAggs(aggConfigs
|
||||
.aggs[0] as IBucketGeoHashGridAggConfig) as IBucketGeoHashGridAggConfig[];
|
||||
const requestAggs = geoHashBucketAgg.getRequestAggs(
|
||||
aggConfigs.aggs[0] as IBucketGeoHashGridAggConfig
|
||||
) as IBucketGeoHashGridAggConfig[];
|
||||
|
||||
expect(requestAggs.length).toEqual(2);
|
||||
expect(requestAggs[0].type.name).toEqual('geohash_grid');
|
||||
|
@ -166,8 +167,9 @@ describe('Geohash Agg', () => {
|
|||
|
||||
it('should only create filter and geohash_grid aggregations when useGeocentroid is false', () => {
|
||||
const aggConfigs = getAggConfigs({ useGeocentroid: false });
|
||||
const requestAggs = geoHashBucketAgg.getRequestAggs(aggConfigs
|
||||
.aggs[0] as IBucketGeoHashGridAggConfig) as IBucketGeoHashGridAggConfig[];
|
||||
const requestAggs = geoHashBucketAgg.getRequestAggs(
|
||||
aggConfigs.aggs[0] as IBucketGeoHashGridAggConfig
|
||||
) as IBucketGeoHashGridAggConfig[];
|
||||
|
||||
expect(requestAggs.length).toEqual(2);
|
||||
expect(requestAggs[0].type.name).toEqual('filter');
|
||||
|
@ -179,36 +181,43 @@ describe('Geohash Agg', () => {
|
|||
let originalRequestAggs: IBucketGeoHashGridAggConfig[];
|
||||
|
||||
beforeEach(() => {
|
||||
originalRequestAggs = geoHashBucketAgg.getRequestAggs(getAggConfigs()
|
||||
.aggs[0] as IBucketGeoHashGridAggConfig) as IBucketGeoHashGridAggConfig[];
|
||||
originalRequestAggs = geoHashBucketAgg.getRequestAggs(
|
||||
getAggConfigs().aggs[0] as IBucketGeoHashGridAggConfig
|
||||
) as IBucketGeoHashGridAggConfig[];
|
||||
});
|
||||
|
||||
it('should change geo_bounding_box filter aggregation and vis session state when map movement is outside map collar', () => {
|
||||
const [, geoBoxingBox] = geoHashBucketAgg.getRequestAggs(getAggConfigs({
|
||||
mapBounds: {
|
||||
top_left: { lat: 10.0, lon: -10.0 },
|
||||
bottom_right: { lat: 9.0, lon: -9.0 },
|
||||
},
|
||||
}).aggs[0] as IBucketGeoHashGridAggConfig) as IBucketGeoHashGridAggConfig[];
|
||||
const [, geoBoxingBox] = geoHashBucketAgg.getRequestAggs(
|
||||
getAggConfigs({
|
||||
mapBounds: {
|
||||
top_left: { lat: 10.0, lon: -10.0 },
|
||||
bottom_right: { lat: 9.0, lon: -9.0 },
|
||||
},
|
||||
}).aggs[0] as IBucketGeoHashGridAggConfig
|
||||
) as IBucketGeoHashGridAggConfig[];
|
||||
|
||||
expect(originalRequestAggs[1].params).not.toEqual(geoBoxingBox.params);
|
||||
});
|
||||
|
||||
it('should not change geo_bounding_box filter aggregation and vis session state when map movement is within map collar', () => {
|
||||
const [, geoBoxingBox] = geoHashBucketAgg.getRequestAggs(getAggConfigs({
|
||||
mapBounds: {
|
||||
top_left: { lat: 1, lon: -1 },
|
||||
bottom_right: { lat: -1, lon: 1 },
|
||||
},
|
||||
}).aggs[0] as IBucketGeoHashGridAggConfig) as IBucketGeoHashGridAggConfig[];
|
||||
const [, geoBoxingBox] = geoHashBucketAgg.getRequestAggs(
|
||||
getAggConfigs({
|
||||
mapBounds: {
|
||||
top_left: { lat: 1, lon: -1 },
|
||||
bottom_right: { lat: -1, lon: 1 },
|
||||
},
|
||||
}).aggs[0] as IBucketGeoHashGridAggConfig
|
||||
) as IBucketGeoHashGridAggConfig[];
|
||||
|
||||
expect(originalRequestAggs[1].params).toEqual(geoBoxingBox.params);
|
||||
});
|
||||
|
||||
it('should change geo_bounding_box filter aggregation and vis session state when map zoom level changes', () => {
|
||||
const [, geoBoxingBox] = geoHashBucketAgg.getRequestAggs(getAggConfigs({
|
||||
mapZoom: -1,
|
||||
}).aggs[0] as IBucketGeoHashGridAggConfig) as IBucketGeoHashGridAggConfig[];
|
||||
const [, geoBoxingBox] = geoHashBucketAgg.getRequestAggs(
|
||||
getAggConfigs({
|
||||
mapZoom: -1,
|
||||
}).aggs[0] as IBucketGeoHashGridAggConfig
|
||||
) as IBucketGeoHashGridAggConfig[];
|
||||
|
||||
expect(originalRequestAggs[1].lastMapCollar).not.toEqual(geoBoxingBox.lastMapCollar);
|
||||
});
|
||||
|
|
|
@ -72,7 +72,10 @@ describe('Range Agg', () => {
|
|||
schema: 'segment',
|
||||
params: {
|
||||
field: 'bytes',
|
||||
ranges: [{ from: 0, to: 1000 }, { from: 1000, to: 2000 }],
|
||||
ranges: [
|
||||
{ from: 0, to: 1000 },
|
||||
{ from: 1000, to: 2000 },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
|
@ -98,7 +98,10 @@ export const rangeBucketAgg = new BucketAggType({
|
|||
},
|
||||
{
|
||||
name: 'ranges',
|
||||
default: [{ from: 0, to: 1000 }, { from: 1000, to: 2000 }],
|
||||
default: [
|
||||
{ from: 0, to: 1000 },
|
||||
{ from: 1000, to: 2000 },
|
||||
],
|
||||
editorComponent: RangesEditor,
|
||||
write(aggConfig: IBucketAggConfig, output: Record<string, any>) {
|
||||
output.params.ranges = aggConfig.params.ranges;
|
||||
|
|
|
@ -59,24 +59,21 @@ function propFilter<P extends string>(prop: P) {
|
|||
return list;
|
||||
}
|
||||
|
||||
const options = filters.reduce(
|
||||
(acc, filter) => {
|
||||
let type = 'include';
|
||||
let value = filter;
|
||||
const options = filters.reduce((acc, filter) => {
|
||||
let type = 'include';
|
||||
let value = filter;
|
||||
|
||||
if (filter.charAt(0) === '!') {
|
||||
type = 'exclude';
|
||||
value = filter.substr(1);
|
||||
}
|
||||
if (filter.charAt(0) === '!') {
|
||||
type = 'exclude';
|
||||
value = filter.substr(1);
|
||||
}
|
||||
|
||||
if (!acc[type]) {
|
||||
acc[type] = [];
|
||||
}
|
||||
acc[type].push(value);
|
||||
return acc;
|
||||
},
|
||||
{} as { [type: string]: string[] }
|
||||
);
|
||||
if (!acc[type]) {
|
||||
acc[type] = [];
|
||||
}
|
||||
acc[type].push(value);
|
||||
return acc;
|
||||
}, {} as { [type: string]: string[] });
|
||||
|
||||
return list.filter(item => {
|
||||
const value = item[prop];
|
||||
|
|
|
@ -58,8 +58,9 @@ export class MetricAggType<
|
|||
config.getValue ||
|
||||
((agg, bucket) => {
|
||||
// Metric types where an empty set equals `zero`
|
||||
const isSettableToZero = [METRIC_TYPES.CARDINALITY, METRIC_TYPES.SUM].includes(agg.type
|
||||
.name as METRIC_TYPES);
|
||||
const isSettableToZero = [METRIC_TYPES.CARDINALITY, METRIC_TYPES.SUM].includes(
|
||||
agg.type.name as METRIC_TYPES
|
||||
);
|
||||
|
||||
// Return proper values when no buckets are present
|
||||
// `Count` handles empty sets properly
|
||||
|
|
|
@ -63,8 +63,9 @@ describe('AggTypesMetricsPercentileRanksProvider class', function() {
|
|||
});
|
||||
|
||||
it('uses the custom label if it is set', function() {
|
||||
const responseAggs: any = percentileRanksMetricAgg.getResponseAggs(aggConfigs
|
||||
.aggs[0] as IPercentileRanksAggConfig);
|
||||
const responseAggs: any = percentileRanksMetricAgg.getResponseAggs(
|
||||
aggConfigs.aggs[0] as IPercentileRanksAggConfig
|
||||
);
|
||||
|
||||
const percentileRankLabelFor5kBytes = responseAggs[0].makeLabel();
|
||||
const percentileRankLabelFor10kBytes = responseAggs[1].makeLabel();
|
||||
|
|
|
@ -63,8 +63,9 @@ describe('AggTypesMetricsPercentilesProvider class', () => {
|
|||
});
|
||||
|
||||
it('uses the custom label if it is set', () => {
|
||||
const responseAggs: any = percentilesMetricAgg.getResponseAggs(aggConfigs
|
||||
.aggs[0] as IPercentileAggConfig);
|
||||
const responseAggs: any = percentilesMetricAgg.getResponseAggs(
|
||||
aggConfigs.aggs[0] as IPercentileAggConfig
|
||||
);
|
||||
|
||||
const ninetyFifthPercentileLabel = responseAggs[0].makeLabel();
|
||||
|
||||
|
|
|
@ -58,8 +58,9 @@ describe('AggTypeMetricStandardDeviationProvider class', () => {
|
|||
|
||||
it('uses the custom label if it is set', () => {
|
||||
const aggConfigs = getAggConfigs('custom label');
|
||||
const responseAggs: any = stdDeviationMetricAgg.getResponseAggs(aggConfigs
|
||||
.aggs[0] as IStdDevAggConfig);
|
||||
const responseAggs: any = stdDeviationMetricAgg.getResponseAggs(
|
||||
aggConfigs.aggs[0] as IStdDevAggConfig
|
||||
);
|
||||
|
||||
const lowerStdDevLabel = responseAggs[0].makeLabel();
|
||||
const upperStdDevLabel = responseAggs[1].makeLabel();
|
||||
|
@ -71,8 +72,9 @@ describe('AggTypeMetricStandardDeviationProvider class', () => {
|
|||
it('uses the default labels if custom label is not set', () => {
|
||||
const aggConfigs = getAggConfigs();
|
||||
|
||||
const responseAggs: any = stdDeviationMetricAgg.getResponseAggs(aggConfigs
|
||||
.aggs[0] as IStdDevAggConfig);
|
||||
const responseAggs: any = stdDeviationMetricAgg.getResponseAggs(
|
||||
aggConfigs.aggs[0] as IStdDevAggConfig
|
||||
);
|
||||
|
||||
const lowerStdDevLabel = responseAggs[0].makeLabel();
|
||||
const upperStdDevLabel = responseAggs[1].makeLabel();
|
||||
|
|
|
@ -248,10 +248,9 @@ describe('DefaultEditorAgg component', () => {
|
|||
expect(compHistogram.find(DefaultEditorAggParams).props()).toHaveProperty('disabledParams', [
|
||||
'min_doc_count',
|
||||
]);
|
||||
expect(compDateHistogram.find(DefaultEditorAggParams).props()).toHaveProperty(
|
||||
'disabledParams',
|
||||
['min_doc_count']
|
||||
);
|
||||
expect(
|
||||
compDateHistogram.find(DefaultEditorAggParams).props()
|
||||
).toHaveProperty('disabledParams', ['min_doc_count']);
|
||||
});
|
||||
|
||||
it('should set error when agg is not histogram or date_histogram', () => {
|
||||
|
|
|
@ -53,13 +53,10 @@ function aggGroupReducer(state: AggsState, action: AggsAction): AggsState {
|
|||
}
|
||||
|
||||
function initAggsState(group: AggConfig[]): AggsState {
|
||||
return group.reduce(
|
||||
(state, agg) => {
|
||||
state[agg.id] = { touched: false, valid: true };
|
||||
return state;
|
||||
},
|
||||
{} as AggsState
|
||||
);
|
||||
return group.reduce((state, agg) => {
|
||||
state[agg.id] = { touched: false, valid: true };
|
||||
return state;
|
||||
}, {} as AggsState);
|
||||
}
|
||||
|
||||
export { aggGroupReducer, initAggsState };
|
||||
|
|
|
@ -121,7 +121,10 @@ describe('DefaultEditorAggParams helpers', () => {
|
|||
},
|
||||
schema: {},
|
||||
getIndexPattern: jest.fn(() => ({
|
||||
fields: [{ name: '@timestamp', type: 'date' }, { name: 'geo_desc', type: 'string' }],
|
||||
fields: [
|
||||
{ name: '@timestamp', type: 'date' },
|
||||
{ name: 'geo_desc', type: 'string' },
|
||||
],
|
||||
})),
|
||||
params: {
|
||||
orderBy: 'orderBy',
|
||||
|
|
|
@ -35,7 +35,10 @@ describe('NumberList utils', () => {
|
|||
let range: Range;
|
||||
|
||||
beforeEach(() => {
|
||||
modelList = [{ value: 1, id: '1', isInvalid: false }, { value: 2, id: '2', isInvalid: false }];
|
||||
modelList = [
|
||||
{ value: 1, id: '1', isInvalid: false },
|
||||
{ value: 2, id: '2', isInvalid: false },
|
||||
];
|
||||
range = {
|
||||
min: 1,
|
||||
max: 10,
|
||||
|
|
|
@ -44,24 +44,21 @@ function groupAndSortBy<
|
|||
TGroupBy extends string = 'type',
|
||||
TLabelName extends string = 'title'
|
||||
>(objects: T[], groupBy: TGroupBy, labelName: TLabelName): ComboBoxGroupedOptions<T> {
|
||||
const groupedOptions = objects.reduce(
|
||||
(array, obj) => {
|
||||
const group = array.find(element => element.label === obj[groupBy]);
|
||||
const option = {
|
||||
label: obj[labelName],
|
||||
target: obj,
|
||||
};
|
||||
const groupedOptions = objects.reduce((array, obj) => {
|
||||
const group = array.find(element => element.label === obj[groupBy]);
|
||||
const option = {
|
||||
label: obj[labelName],
|
||||
target: obj,
|
||||
};
|
||||
|
||||
if (group && group.options) {
|
||||
group.options.push(option);
|
||||
} else {
|
||||
array.push({ label: obj[groupBy], options: [option] });
|
||||
}
|
||||
if (group && group.options) {
|
||||
group.options.push(option);
|
||||
} else {
|
||||
array.push({ label: obj[groupBy], options: [option] });
|
||||
}
|
||||
|
||||
return array;
|
||||
},
|
||||
[] as Array<ComboBoxGroupedOption<T>>
|
||||
);
|
||||
return array;
|
||||
}, [] as Array<ComboBoxGroupedOption<T>>);
|
||||
|
||||
groupedOptions.sort(sortByLabel);
|
||||
|
||||
|
|
|
@ -172,7 +172,10 @@ describe('visualize loader pipeline helpers: build pipeline', () => {
|
|||
const visState = { ...visStateDef, params: { foo: 'bar' } };
|
||||
const schemas = {
|
||||
...schemasDef,
|
||||
metric: [{ ...schemaConfig, accessor: 0 }, { ...schemaConfig, accessor: 1 }],
|
||||
metric: [
|
||||
{ ...schemaConfig, accessor: 0 },
|
||||
{ ...schemaConfig, accessor: 1 },
|
||||
],
|
||||
};
|
||||
const actual = buildPipelineVisFunction.table(visState, schemas, uiState);
|
||||
expect(actual).toMatchSnapshot();
|
||||
|
@ -192,7 +195,10 @@ describe('visualize loader pipeline helpers: build pipeline', () => {
|
|||
const visState = { ...visStateDef, params: { foo: 'bar' } };
|
||||
const schemas = {
|
||||
...schemasDef,
|
||||
metric: [{ ...schemaConfig, accessor: 0 }, { ...schemaConfig, accessor: 1 }],
|
||||
metric: [
|
||||
{ ...schemaConfig, accessor: 0 },
|
||||
{ ...schemaConfig, accessor: 1 },
|
||||
],
|
||||
split_row: [2, 4],
|
||||
bucket: [3],
|
||||
};
|
||||
|
@ -250,7 +256,10 @@ describe('visualize loader pipeline helpers: build pipeline', () => {
|
|||
const visState = { ...visStateDef, params: { metric: {} } };
|
||||
const schemas = {
|
||||
...schemasDef,
|
||||
metric: [{ ...schemaConfig, accessor: 0 }, { ...schemaConfig, accessor: 1 }],
|
||||
metric: [
|
||||
{ ...schemaConfig, accessor: 0 },
|
||||
{ ...schemaConfig, accessor: 1 },
|
||||
],
|
||||
};
|
||||
const actual = buildPipelineVisFunction.metric(visState, schemas, uiState);
|
||||
expect(actual).toMatchSnapshot();
|
||||
|
@ -260,7 +269,10 @@ describe('visualize loader pipeline helpers: build pipeline', () => {
|
|||
const visState = { ...visStateDef, params: { metric: {} } };
|
||||
const schemas = {
|
||||
...schemasDef,
|
||||
metric: [{ ...schemaConfig, accessor: 0 }, { ...schemaConfig, accessor: 1 }],
|
||||
metric: [
|
||||
{ ...schemaConfig, accessor: 0 },
|
||||
{ ...schemaConfig, accessor: 1 },
|
||||
],
|
||||
group: [{ accessor: 2 }],
|
||||
};
|
||||
const actual = buildPipelineVisFunction.metric(visState, schemas, uiState);
|
||||
|
|
|
@ -61,9 +61,10 @@ export class DashboardEmbeddableContainerPublicPlugin
|
|||
const { application, notifications, overlays } = core;
|
||||
const { embeddable, inspector, uiActions } = plugins;
|
||||
|
||||
const SavedObjectFinder: React.FC<
|
||||
Exclude<SavedObjectFinderProps, 'savedObjects' | 'uiSettings'>
|
||||
> = props => (
|
||||
const SavedObjectFinder: React.FC<Exclude<
|
||||
SavedObjectFinderProps,
|
||||
'savedObjects' | 'uiSettings'
|
||||
>> = props => (
|
||||
<SavedObjectFinderUi
|
||||
{...props}
|
||||
savedObjects={core.savedObjects}
|
||||
|
|
|
@ -30,7 +30,10 @@ describe('filter manager utilities', () => {
|
|||
},
|
||||
geo_polygon: {
|
||||
point: {
|
||||
points: [{ lat: 5, lon: 10 }, { lat: 15, lon: 20 }],
|
||||
points: [
|
||||
{ lat: 5, lon: 10 },
|
||||
{ lat: 15, lon: 20 },
|
||||
],
|
||||
},
|
||||
},
|
||||
} as esFilters.GeoPolygonFilter;
|
||||
|
|
|
@ -62,8 +62,10 @@ describe('Create app mount search context', () => {
|
|||
});
|
||||
},
|
||||
});
|
||||
context
|
||||
.search({ greeting: 'hi' } as any, {}, 'mysearch')
|
||||
.subscribe(response => {}, () => {}, done);
|
||||
context.search({ greeting: 'hi' } as any, {}, 'mysearch').subscribe(
|
||||
response => {},
|
||||
() => {},
|
||||
done
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -69,24 +69,21 @@ export const stripEmptyFields = (
|
|||
): { [key: string]: any } => {
|
||||
const { types = ['string', 'object'], recursive = false } = options || {};
|
||||
|
||||
return Object.entries(object).reduce(
|
||||
(acc, [key, value]) => {
|
||||
const type = typeof value;
|
||||
const shouldStrip = types.includes(type as 'string');
|
||||
return Object.entries(object).reduce((acc, [key, value]) => {
|
||||
const type = typeof value;
|
||||
const shouldStrip = types.includes(type as 'string');
|
||||
|
||||
if (shouldStrip && type === 'string' && value.trim() === '') {
|
||||
return acc;
|
||||
} else if (type === 'object' && !Array.isArray(value) && value !== null) {
|
||||
if (Object.keys(value).length === 0 && shouldStrip) {
|
||||
return acc;
|
||||
} else if (recursive) {
|
||||
value = stripEmptyFields({ ...value }, options);
|
||||
}
|
||||
}
|
||||
|
||||
acc[key] = value;
|
||||
if (shouldStrip && type === 'string' && value.trim() === '') {
|
||||
return acc;
|
||||
},
|
||||
{} as { [key: string]: any }
|
||||
);
|
||||
} else if (type === 'object' && !Array.isArray(value) && value !== null) {
|
||||
if (Object.keys(value).length === 0 && shouldStrip) {
|
||||
return acc;
|
||||
} else if (recursive) {
|
||||
value = stripEmptyFields({ ...value }, options);
|
||||
}
|
||||
}
|
||||
|
||||
acc[key] = value;
|
||||
return acc;
|
||||
}, {} as { [key: string]: any });
|
||||
};
|
||||
|
|
|
@ -65,15 +65,12 @@ export function useForm<T extends object = FormData>(
|
|||
|
||||
const stripEmptyFields = (fields: FieldsMap): FieldsMap => {
|
||||
if (formOptions.stripEmptyFields) {
|
||||
return Object.entries(fields).reduce(
|
||||
(acc, [key, field]) => {
|
||||
if (typeof field.value !== 'string' || field.value.trim() !== '') {
|
||||
acc[key] = field;
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{} as FieldsMap
|
||||
);
|
||||
return Object.entries(fields).reduce((acc, [key, field]) => {
|
||||
if (typeof field.value !== 'string' || field.value.trim() !== '') {
|
||||
acc[key] = field;
|
||||
}
|
||||
return acc;
|
||||
}, {} as FieldsMap);
|
||||
}
|
||||
return fields;
|
||||
};
|
||||
|
|
|
@ -50,10 +50,7 @@ export const mapFormFields = (
|
|||
formFields: Record<string, FieldHook>,
|
||||
fn: (field: FieldHook) => any
|
||||
) =>
|
||||
Object.entries(formFields).reduce(
|
||||
(acc, [key, field]) => {
|
||||
acc[key] = fn(field);
|
||||
return acc;
|
||||
},
|
||||
{} as Record<string, unknown>
|
||||
);
|
||||
Object.entries(formFields).reduce((acc, [key, field]) => {
|
||||
acc[key] = fn(field);
|
||||
return acc;
|
||||
}, {} as Record<string, unknown>);
|
||||
|
|
|
@ -163,9 +163,9 @@ export function interpreterProvider(config: InterpreterConfig): ExpressionInterp
|
|||
|
||||
// Check for missing required arguments
|
||||
each(argDefs, argDef => {
|
||||
const { aliases, default: argDefault, name: argName, required } = argDef as (ArgumentType<
|
||||
const { aliases, default: argDefault, name: argName, required } = argDef as ArgumentType<
|
||||
any
|
||||
> & { name: string });
|
||||
> & { name: string };
|
||||
if (
|
||||
typeof argDefault === 'undefined' &&
|
||||
required &&
|
||||
|
|
|
@ -32,12 +32,11 @@ const defaultContextValue = {
|
|||
|
||||
export const context = createContext<KibanaReactContextValue<KibanaServices>>(defaultContextValue);
|
||||
|
||||
export const useKibana = <Extra extends object = {}>(): KibanaReactContextValue<
|
||||
KibanaServices & Extra
|
||||
> =>
|
||||
useContext((context as unknown) as React.Context<
|
||||
KibanaReactContextValue<KibanaServices & Extra>
|
||||
>);
|
||||
export const useKibana = <Extra extends object = {}>(): KibanaReactContextValue<KibanaServices &
|
||||
Extra> =>
|
||||
useContext(
|
||||
(context as unknown) as React.Context<KibanaReactContextValue<KibanaServices & Extra>>
|
||||
);
|
||||
|
||||
export const withKibana = <Props extends { kibana: KibanaReactContextValue<any> }>(
|
||||
type: React.ComponentType<Props>
|
||||
|
|
|
@ -305,9 +305,9 @@ export function VisualBuilderPageProvider({ getService, getPageObjects }: FtrPro
|
|||
|
||||
public async getRhythmChartLegendValue(nth = 0) {
|
||||
await PageObjects.visualize.waitForVisualizationRenderingStabilized();
|
||||
const metricValue = (await find.allByCssSelector(
|
||||
`.echLegendItem .echLegendItem__displayValue`
|
||||
))[nth];
|
||||
const metricValue = (
|
||||
await find.allByCssSelector(`.echLegendItem .echLegendItem__displayValue`)
|
||||
)[nth];
|
||||
await metricValue.moveMouseTo();
|
||||
return await metricValue.getVisibleText();
|
||||
}
|
||||
|
|
|
@ -56,10 +56,7 @@ export function pollForLogEntry$(driver: WebDriver, type: string, ms: number) {
|
|||
[new logging.Entry('SEVERE', `ERROR FETCHING BROWSR LOGS: ${error.message}`)],
|
||||
|
||||
// pause 10 seconds then resubscribe
|
||||
Rx.of(1).pipe(
|
||||
delay(10 * 1000),
|
||||
mergeMapTo(resubscribe)
|
||||
)
|
||||
Rx.of(1).pipe(delay(10 * 1000), mergeMapTo(resubscribe))
|
||||
);
|
||||
})
|
||||
);
|
||||
|
|
|
@ -53,9 +53,7 @@ import { DEMO_SEARCH_STRATEGY, IDemoResponse } from '../common';
|
|||
* @param context - context supplied by other plugins.
|
||||
* @param search - a search function to access other strategies that have already been registered.
|
||||
*/
|
||||
export const demoClientSearchStrategyProvider: TSearchStrategyProvider<
|
||||
typeof DEMO_SEARCH_STRATEGY
|
||||
> = (
|
||||
export const demoClientSearchStrategyProvider: TSearchStrategyProvider<typeof DEMO_SEARCH_STRATEGY> = (
|
||||
context: ISearchContext,
|
||||
search: ISearchGeneric
|
||||
): ISearchStrategy<typeof DEMO_SEARCH_STRATEGY> => {
|
||||
|
|
|
@ -20,9 +20,7 @@
|
|||
import { TSearchStrategyProvider } from 'src/plugins/data/server';
|
||||
import { DEMO_SEARCH_STRATEGY } from '../common';
|
||||
|
||||
export const demoSearchStrategyProvider: TSearchStrategyProvider<
|
||||
typeof DEMO_SEARCH_STRATEGY
|
||||
> = () => {
|
||||
export const demoSearchStrategyProvider: TSearchStrategyProvider<typeof DEMO_SEARCH_STRATEGY> = () => {
|
||||
return {
|
||||
search: request => {
|
||||
return Promise.resolve({
|
||||
|
|
|
@ -8,7 +8,7 @@ import React from 'react';
|
|||
import { EuiDraggable, EuiDragDropContext } from '@elastic/eui';
|
||||
|
||||
type PropsOf<T> = T extends React.ComponentType<infer ComponentProps> ? ComponentProps : never;
|
||||
type FirstArgumentOf<Func> = Func extends ((arg1: infer FirstArgument, ...rest: any[]) => any)
|
||||
type FirstArgumentOf<Func> = Func extends (arg1: infer FirstArgument, ...rest: any[]) => any
|
||||
? FirstArgument
|
||||
: never;
|
||||
export type DragHandleProps = FirstArgumentOf<
|
||||
|
|
|
@ -111,11 +111,9 @@ test('executes the task by calling the executor with proper parameters', async (
|
|||
|
||||
expect(runnerResult).toBeUndefined();
|
||||
expect(spaceIdToNamespace).toHaveBeenCalledWith('test');
|
||||
expect(mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser).toHaveBeenCalledWith(
|
||||
'action_task_params',
|
||||
'3',
|
||||
{ namespace: 'namespace-test' }
|
||||
);
|
||||
expect(
|
||||
mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser
|
||||
).toHaveBeenCalledWith('action_task_params', '3', { namespace: 'namespace-test' });
|
||||
expect(mockedActionExecutor.execute).toHaveBeenCalledWith({
|
||||
actionId: '2',
|
||||
params: { baz: true },
|
||||
|
|
|
@ -21,14 +21,14 @@ type SourceProjection = Omit<DeepPartial<ESSearchRequest>, 'body'> & {
|
|||
};
|
||||
|
||||
type DeepMerge<T, U> = U extends PlainObject
|
||||
? (T extends PlainObject
|
||||
? (Omit<T, keyof U> &
|
||||
{
|
||||
[key in keyof U]: T extends { [k in key]: any }
|
||||
? DeepMerge<T[key], U[key]>
|
||||
: U[key];
|
||||
})
|
||||
: U)
|
||||
? T extends PlainObject
|
||||
? Omit<T, keyof U> &
|
||||
{
|
||||
[key in keyof U]: T extends { [k in key]: any }
|
||||
? DeepMerge<T[key], U[key]>
|
||||
: U[key];
|
||||
}
|
||||
: U
|
||||
: U;
|
||||
|
||||
export function mergeProjection<
|
||||
|
|
|
@ -29,9 +29,7 @@ export function ServiceMetrics({ agentName }: ServiceMetricsProps) {
|
|||
const { data } = useServiceMetricCharts(urlParams, agentName);
|
||||
const { start, end } = urlParams;
|
||||
|
||||
const localFiltersConfig: React.ComponentProps<
|
||||
typeof LocalUIFilters
|
||||
> = useMemo(
|
||||
const localFiltersConfig: React.ComponentProps<typeof LocalUIFilters> = useMemo(
|
||||
() => ({
|
||||
filterNames: ['host', 'containerId', 'podName'],
|
||||
params: {
|
||||
|
|
|
@ -34,9 +34,7 @@ const ServiceNodeOverview = () => {
|
|||
const { uiFilters, urlParams } = useUrlParams();
|
||||
const { serviceName, start, end } = urlParams;
|
||||
|
||||
const localFiltersConfig: React.ComponentProps<
|
||||
typeof LocalUIFilters
|
||||
> = useMemo(
|
||||
const localFiltersConfig: React.ComponentProps<typeof LocalUIFilters> = useMemo(
|
||||
() => ({
|
||||
filterNames: ['host', 'containerId', 'podName'],
|
||||
params: {
|
||||
|
|
|
@ -84,9 +84,7 @@ export function ServiceOverview() {
|
|||
useTrackPageview({ app: 'apm', path: 'services_overview' });
|
||||
useTrackPageview({ app: 'apm', path: 'services_overview', delay: 15000 });
|
||||
|
||||
const localFiltersConfig: React.ComponentProps<
|
||||
typeof LocalUIFilters
|
||||
> = useMemo(
|
||||
const localFiltersConfig: React.ComponentProps<typeof LocalUIFilters> = useMemo(
|
||||
() => ({
|
||||
filterNames: ['host', 'agentName'],
|
||||
projection: PROJECTION.SERVICES
|
||||
|
|
|
@ -195,10 +195,9 @@ export const TransactionDistribution: FunctionComponent<Props> = (
|
|||
}
|
||||
backgroundHover={(bucket: IChartPoint) => bucket.y > 0 && bucket.sample}
|
||||
tooltipHeader={(bucket: IChartPoint) =>
|
||||
`${timeFormatter(bucket.x0, { withUnit: false })} - ${timeFormatter(
|
||||
bucket.x,
|
||||
{ withUnit: false }
|
||||
)} ${unit}`
|
||||
`${timeFormatter(bucket.x0, {
|
||||
withUnit: false
|
||||
})} - ${timeFormatter(bucket.x, { withUnit: false })} ${unit}`
|
||||
}
|
||||
tooltipFooter={(bucket: IChartPoint) =>
|
||||
!bucket.sample &&
|
||||
|
|
|
@ -94,9 +94,7 @@ export function TransactionOverview() {
|
|||
}
|
||||
}, [http, serviceName, transactionType]);
|
||||
|
||||
const localFiltersConfig: React.ComponentProps<
|
||||
typeof LocalUIFilters
|
||||
> = useMemo(
|
||||
const localFiltersConfig: React.ComponentProps<typeof LocalUIFilters> = useMemo(
|
||||
() => ({
|
||||
filterNames: ['transactionResult', 'host', 'containerId', 'podName'],
|
||||
params: {
|
||||
|
|
|
@ -103,12 +103,14 @@ export function KueryBar() {
|
|||
|
||||
const boolFilter = getBoolFilter(urlParams);
|
||||
try {
|
||||
const suggestions = (await getSuggestions(
|
||||
inputValue,
|
||||
selectionStart,
|
||||
indexPattern,
|
||||
boolFilter
|
||||
))
|
||||
const suggestions = (
|
||||
await getSuggestions(
|
||||
inputValue,
|
||||
selectionStart,
|
||||
indexPattern,
|
||||
boolFilter
|
||||
)
|
||||
)
|
||||
.filter(suggestion => !startsWith(suggestion.text, 'span.'))
|
||||
.slice(0, 15);
|
||||
|
||||
|
|
|
@ -21,7 +21,10 @@ describe('MetadataTable', () => {
|
|||
label: 'Bar',
|
||||
required: false,
|
||||
properties: ['props.A', 'props.B'],
|
||||
rows: [{ key: 'props.A', value: 'A' }, { key: 'props.B', value: 'B' }]
|
||||
rows: [
|
||||
{ key: 'props.A', value: 'A' },
|
||||
{ key: 'props.B', value: 'B' }
|
||||
]
|
||||
}
|
||||
] as unknown) as SectionsWithRows;
|
||||
const output = render(<MetadataTable sections={sectionsWithRows} />);
|
||||
|
|
|
@ -76,29 +76,26 @@ interface StackframesGroup {
|
|||
}
|
||||
|
||||
export function getGroupedStackframes(stackframes: IStackframe[]) {
|
||||
return stackframes.reduce(
|
||||
(acc, stackframe) => {
|
||||
const prevGroup = last(acc);
|
||||
const shouldAppend =
|
||||
prevGroup &&
|
||||
prevGroup.isLibraryFrame === stackframe.library_frame &&
|
||||
!prevGroup.excludeFromGrouping &&
|
||||
!stackframe.exclude_from_grouping;
|
||||
return stackframes.reduce((acc, stackframe) => {
|
||||
const prevGroup = last(acc);
|
||||
const shouldAppend =
|
||||
prevGroup &&
|
||||
prevGroup.isLibraryFrame === stackframe.library_frame &&
|
||||
!prevGroup.excludeFromGrouping &&
|
||||
!stackframe.exclude_from_grouping;
|
||||
|
||||
// append to group
|
||||
if (shouldAppend) {
|
||||
prevGroup.stackframes.push(stackframe);
|
||||
return acc;
|
||||
}
|
||||
|
||||
// create new group
|
||||
acc.push({
|
||||
isLibraryFrame: Boolean(stackframe.library_frame),
|
||||
excludeFromGrouping: Boolean(stackframe.exclude_from_grouping),
|
||||
stackframes: [stackframe]
|
||||
});
|
||||
// append to group
|
||||
if (shouldAppend) {
|
||||
prevGroup.stackframes.push(stackframe);
|
||||
return acc;
|
||||
},
|
||||
[] as StackframesGroup[]
|
||||
);
|
||||
}
|
||||
|
||||
// create new group
|
||||
acc.push({
|
||||
isLibraryFrame: Boolean(stackframe.library_frame),
|
||||
excludeFromGrouping: Boolean(stackframe.exclude_from_grouping),
|
||||
stackframes: [stackframe]
|
||||
});
|
||||
return acc;
|
||||
}, [] as StackframesGroup[]);
|
||||
}
|
||||
|
|
|
@ -32,7 +32,10 @@ class VoronoiPlot extends PureComponent {
|
|||
onMouseLeave={this.props.onMouseLeave}
|
||||
>
|
||||
<Voronoi
|
||||
extent={[[XY_MARGIN.left, XY_MARGIN.top], [XY_WIDTH, XY_HEIGHT]]}
|
||||
extent={[
|
||||
[XY_MARGIN.left, XY_MARGIN.top],
|
||||
[XY_WIDTH, XY_HEIGHT]
|
||||
]}
|
||||
nodes={xValuesCombined}
|
||||
onHover={this.props.onHover}
|
||||
onMouseDown={this.props.onMouseDown}
|
||||
|
|
|
@ -38,10 +38,9 @@ describe('Histogram', () => {
|
|||
formatYShort={t => `${asDecimal(t)} occ.`}
|
||||
formatYLong={t => `${asDecimal(t)} occurrences`}
|
||||
tooltipHeader={bucket =>
|
||||
`${timeFormatter(bucket.x0, { withUnit: false })} - ${timeFormatter(
|
||||
bucket.x,
|
||||
{ withUnit: false }
|
||||
)} ${unit}`
|
||||
`${timeFormatter(bucket.x0, {
|
||||
withUnit: false
|
||||
})} - ${timeFormatter(bucket.x, { withUnit: false })} ${unit}`
|
||||
}
|
||||
width={800}
|
||||
/>
|
||||
|
|
|
@ -209,7 +209,10 @@ export class HistogramInner extends PureComponent {
|
|||
)}
|
||||
|
||||
<Voronoi
|
||||
extent={[[XY_MARGIN.left, XY_MARGIN.top], [XY_WIDTH, XY_HEIGHT]]}
|
||||
extent={[
|
||||
[XY_MARGIN.left, XY_MARGIN.top],
|
||||
[XY_WIDTH, XY_HEIGHT]
|
||||
]}
|
||||
nodes={this.props.buckets.map(bucket => {
|
||||
return {
|
||||
...bucket,
|
||||
|
|
|
@ -35,9 +35,18 @@ describe('chartSelectors', () => {
|
|||
describe('getResponseTimeSeries', () => {
|
||||
const apmTimeseries = {
|
||||
responseTimes: {
|
||||
avg: [{ x: 0, y: 100 }, { x: 1000, y: 200 }],
|
||||
p95: [{ x: 0, y: 200 }, { x: 1000, y: 300 }],
|
||||
p99: [{ x: 0, y: 300 }, { x: 1000, y: 400 }]
|
||||
avg: [
|
||||
{ x: 0, y: 100 },
|
||||
{ x: 1000, y: 200 }
|
||||
],
|
||||
p95: [
|
||||
{ x: 0, y: 200 },
|
||||
{ x: 1000, y: 300 }
|
||||
],
|
||||
p99: [
|
||||
{ x: 0, y: 300 },
|
||||
{ x: 1000, y: 400 }
|
||||
]
|
||||
},
|
||||
tpmBuckets: [],
|
||||
overallAvgDuration: 200
|
||||
|
@ -49,21 +58,30 @@ describe('chartSelectors', () => {
|
|||
).toEqual([
|
||||
{
|
||||
color: '#3185fc',
|
||||
data: [{ x: 0, y: 100 }, { x: 1000, y: 200 }],
|
||||
data: [
|
||||
{ x: 0, y: 100 },
|
||||
{ x: 1000, y: 200 }
|
||||
],
|
||||
legendValue: '0 ms',
|
||||
title: 'Avg.',
|
||||
type: 'linemark'
|
||||
},
|
||||
{
|
||||
color: '#e6c220',
|
||||
data: [{ x: 0, y: 200 }, { x: 1000, y: 300 }],
|
||||
data: [
|
||||
{ x: 0, y: 200 },
|
||||
{ x: 1000, y: 300 }
|
||||
],
|
||||
title: '95th percentile',
|
||||
titleShort: '95th',
|
||||
type: 'linemark'
|
||||
},
|
||||
{
|
||||
color: '#f98510',
|
||||
data: [{ x: 0, y: 300 }, { x: 1000, y: 400 }],
|
||||
data: [
|
||||
{ x: 0, y: 300 },
|
||||
{ x: 1000, y: 400 }
|
||||
],
|
||||
title: '99th percentile',
|
||||
titleShort: '99th',
|
||||
type: 'linemark'
|
||||
|
@ -87,7 +105,13 @@ describe('chartSelectors', () => {
|
|||
p99: []
|
||||
},
|
||||
tpmBuckets: [
|
||||
{ key: 'HTTP 2xx', dataPoints: [{ x: 0, y: 5 }, { x: 0, y: 2 }] },
|
||||
{
|
||||
key: 'HTTP 2xx',
|
||||
dataPoints: [
|
||||
{ x: 0, y: 5 },
|
||||
{ x: 0, y: 2 }
|
||||
]
|
||||
},
|
||||
{ key: 'HTTP 4xx', dataPoints: [{ x: 0, y: 1 }] },
|
||||
{ key: 'HTTP 5xx', dataPoints: [{ x: 0, y: 0 }] }
|
||||
],
|
||||
|
@ -99,7 +123,10 @@ describe('chartSelectors', () => {
|
|||
expect(getTpmSeries(apmTimeseries, transactionType)).toEqual([
|
||||
{
|
||||
color: successColor,
|
||||
data: [{ x: 0, y: 5 }, { x: 0, y: 2 }],
|
||||
data: [
|
||||
{ x: 0, y: 5 },
|
||||
{ x: 0, y: 2 }
|
||||
],
|
||||
legendValue: '3.5 tpm',
|
||||
title: 'HTTP 2xx',
|
||||
type: 'linemark'
|
||||
|
@ -220,9 +247,18 @@ describe('chartSelectors', () => {
|
|||
describe('when empty', () => {
|
||||
it('produces an empty series', () => {
|
||||
const responseTimes = {
|
||||
avg: [{ x: 0, y: 1 }, { x: 100, y: 1 }],
|
||||
p95: [{ x: 0, y: 1 }, { x: 100, y: 1 }],
|
||||
p99: [{ x: 0, y: 1 }, { x: 100, y: 1 }]
|
||||
avg: [
|
||||
{ x: 0, y: 1 },
|
||||
{ x: 100, y: 1 }
|
||||
],
|
||||
p95: [
|
||||
{ x: 0, y: 1 },
|
||||
{ x: 100, y: 1 }
|
||||
],
|
||||
p99: [
|
||||
{ x: 0, y: 1 },
|
||||
{ x: 100, y: 1 }
|
||||
]
|
||||
};
|
||||
const series = getTpmSeries(
|
||||
{ ...apmTimeseries, responseTimes, tpmBuckets: [] },
|
||||
|
|
|
@ -151,56 +151,53 @@ export async function getTransactionBreakdown({
|
|||
|
||||
const bucketsByDate = idx(resp.aggregations, _ => _.by_date.buckets) || [];
|
||||
|
||||
const timeseriesPerSubtype = bucketsByDate.reduce(
|
||||
(prev, bucket) => {
|
||||
const formattedValues = formatBucket(bucket);
|
||||
const time = bucket.key;
|
||||
const timeseriesPerSubtype = bucketsByDate.reduce((prev, bucket) => {
|
||||
const formattedValues = formatBucket(bucket);
|
||||
const time = bucket.key;
|
||||
|
||||
const updatedSeries = kpiNames.reduce((p, kpiName) => {
|
||||
const { name, percentage } = formattedValues.find(
|
||||
val => val.name === kpiName
|
||||
) || {
|
||||
name: kpiName,
|
||||
percentage: null
|
||||
};
|
||||
const updatedSeries = kpiNames.reduce((p, kpiName) => {
|
||||
const { name, percentage } = formattedValues.find(
|
||||
val => val.name === kpiName
|
||||
) || {
|
||||
name: kpiName,
|
||||
percentage: null
|
||||
};
|
||||
|
||||
if (!p[name]) {
|
||||
p[name] = [];
|
||||
}
|
||||
return {
|
||||
...p,
|
||||
[name]: p[name].concat({
|
||||
x: time,
|
||||
y: percentage
|
||||
})
|
||||
};
|
||||
}, prev);
|
||||
|
||||
const lastValues = Object.values(updatedSeries).map(last);
|
||||
|
||||
// If for a given timestamp, some series have data, but others do not,
|
||||
// we have to set any null values to 0 to make sure the stacked area chart
|
||||
// is drawn correctly.
|
||||
// If we set all values to 0, the chart always displays null values as 0,
|
||||
// and the chart looks weird.
|
||||
const hasAnyValues = lastValues.some(value => value.y !== null);
|
||||
const hasNullValues = lastValues.some(value => value.y === null);
|
||||
|
||||
if (hasAnyValues && hasNullValues) {
|
||||
Object.values(updatedSeries).forEach(series => {
|
||||
const value = series[series.length - 1];
|
||||
const isEmpty = value.y === null;
|
||||
if (isEmpty) {
|
||||
// local mutation to prevent complicated map/reduce calls
|
||||
value.y = 0;
|
||||
}
|
||||
});
|
||||
if (!p[name]) {
|
||||
p[name] = [];
|
||||
}
|
||||
return {
|
||||
...p,
|
||||
[name]: p[name].concat({
|
||||
x: time,
|
||||
y: percentage
|
||||
})
|
||||
};
|
||||
}, prev);
|
||||
|
||||
return updatedSeries;
|
||||
},
|
||||
{} as Record<string, Array<{ x: number; y: number | null }>>
|
||||
);
|
||||
const lastValues = Object.values(updatedSeries).map(last);
|
||||
|
||||
// If for a given timestamp, some series have data, but others do not,
|
||||
// we have to set any null values to 0 to make sure the stacked area chart
|
||||
// is drawn correctly.
|
||||
// If we set all values to 0, the chart always displays null values as 0,
|
||||
// and the chart looks weird.
|
||||
const hasAnyValues = lastValues.some(value => value.y !== null);
|
||||
const hasNullValues = lastValues.some(value => value.y === null);
|
||||
|
||||
if (hasAnyValues && hasNullValues) {
|
||||
Object.values(updatedSeries).forEach(series => {
|
||||
const value = series[series.length - 1];
|
||||
const isEmpty = value.y === null;
|
||||
if (isEmpty) {
|
||||
// local mutation to prevent complicated map/reduce calls
|
||||
value.y = 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return updatedSeries;
|
||||
}, {} as Record<string, Array<{ x: number; y: number | null }>>);
|
||||
|
||||
const timeseries = kpis.map(kpi => ({
|
||||
title: kpi.name,
|
||||
|
|
|
@ -61,17 +61,14 @@ export const localUIFilterNames = Object.keys(
|
|||
filtersByName
|
||||
) as LocalUIFilterName[];
|
||||
|
||||
export const localUIFilters = localUIFilterNames.reduce(
|
||||
(acc, key) => {
|
||||
const field = filtersByName[key];
|
||||
export const localUIFilters = localUIFilterNames.reduce((acc, key) => {
|
||||
const field = filtersByName[key];
|
||||
|
||||
return {
|
||||
...acc,
|
||||
[key]: {
|
||||
...field,
|
||||
name: key
|
||||
}
|
||||
};
|
||||
},
|
||||
{} as LocalUIFilterMap
|
||||
);
|
||||
return {
|
||||
...acc,
|
||||
[key]: {
|
||||
...field,
|
||||
name: key
|
||||
}
|
||||
};
|
||||
}, {} as LocalUIFilterMap);
|
||||
|
|
|
@ -68,41 +68,38 @@ export function createApi() {
|
|||
|
||||
const parsedParams = (Object.keys(rts) as Array<
|
||||
keyof typeof rts
|
||||
>).reduce(
|
||||
(acc, key) => {
|
||||
const codec = rts[key];
|
||||
const value = paramMap[key];
|
||||
>).reduce((acc, key) => {
|
||||
const codec = rts[key];
|
||||
const value = paramMap[key];
|
||||
|
||||
const result = codec.decode(value);
|
||||
const result = codec.decode(value);
|
||||
|
||||
if (isLeft(result)) {
|
||||
throw Boom.badRequest(PathReporter.report(result)[0]);
|
||||
}
|
||||
if (isLeft(result)) {
|
||||
throw Boom.badRequest(PathReporter.report(result)[0]);
|
||||
}
|
||||
|
||||
const strippedKeys = difference(
|
||||
Object.keys(value || {}),
|
||||
Object.keys(result.right || {})
|
||||
const strippedKeys = difference(
|
||||
Object.keys(value || {}),
|
||||
Object.keys(result.right || {})
|
||||
);
|
||||
|
||||
if (strippedKeys.length) {
|
||||
throw Boom.badRequest(
|
||||
`Unknown keys specified: ${strippedKeys}`
|
||||
);
|
||||
}
|
||||
|
||||
if (strippedKeys.length) {
|
||||
throw Boom.badRequest(
|
||||
`Unknown keys specified: ${strippedKeys}`
|
||||
);
|
||||
}
|
||||
// hide _debug from route handlers
|
||||
const parsedValue =
|
||||
key === 'query'
|
||||
? omit(result.right, '_debug')
|
||||
: result.right;
|
||||
|
||||
// hide _debug from route handlers
|
||||
const parsedValue =
|
||||
key === 'query'
|
||||
? omit(result.right, '_debug')
|
||||
: result.right;
|
||||
|
||||
return {
|
||||
...acc,
|
||||
[key]: parsedValue
|
||||
};
|
||||
},
|
||||
{} as Record<keyof typeof params, any>
|
||||
);
|
||||
return {
|
||||
...acc,
|
||||
[key]: parsedValue
|
||||
};
|
||||
}, {} as Record<keyof typeof params, any>);
|
||||
|
||||
return route.handler(
|
||||
request,
|
||||
|
|
|
@ -95,7 +95,9 @@ type GetOptionalParamKeys<TParams extends Params> = keyof PickByValue<
|
|||
{
|
||||
[key in keyof TParams]: TParams[key] extends t.PartialType<any>
|
||||
? false
|
||||
: (TParams[key] extends t.Any ? true : false);
|
||||
: TParams[key] extends t.Any
|
||||
? true
|
||||
: false;
|
||||
},
|
||||
false
|
||||
>;
|
||||
|
|
|
@ -45,9 +45,11 @@ export const uiFiltersEnvironmentsRoute = createRoute(() => ({
|
|||
const filterNamesRt = t.type({
|
||||
filterNames: jsonRt.pipe(
|
||||
t.array(
|
||||
t.keyof(Object.fromEntries(
|
||||
localUIFilterNames.map(filterName => [filterName, null])
|
||||
) as Record<LocalUIFilterName, null>)
|
||||
t.keyof(
|
||||
Object.fromEntries(
|
||||
localUIFilterNames.map(filterName => [filterName, null])
|
||||
) as Record<LocalUIFilterName, null>
|
||||
)
|
||||
)
|
||||
)
|
||||
});
|
||||
|
|
|
@ -202,22 +202,19 @@ interface AggregationResponsePart<
|
|||
TDocument
|
||||
>
|
||||
>
|
||||
: (TAggregationOptionsMap extends {
|
||||
: TAggregationOptionsMap extends {
|
||||
filters: {
|
||||
filters: Record<string, any>;
|
||||
};
|
||||
}
|
||||
? {
|
||||
buckets: {
|
||||
[key in keyof TAggregationOptionsMap['filters']['filters']]: {
|
||||
doc_count: number;
|
||||
} & AggregationResponseMap<
|
||||
TAggregationOptionsMap['aggs'],
|
||||
TDocument
|
||||
>;
|
||||
};
|
||||
}
|
||||
: never);
|
||||
? {
|
||||
buckets: {
|
||||
[key in keyof TAggregationOptionsMap['filters']['filters']]: {
|
||||
doc_count: number;
|
||||
} & AggregationResponseMap<TAggregationOptionsMap['aggs'], TDocument>;
|
||||
};
|
||||
}
|
||||
: never;
|
||||
sampler: {
|
||||
doc_count: number;
|
||||
} & AggregationResponseMap<TAggregationOptionsMap['aggs'], TDocument>;
|
||||
|
|
|
@ -36,8 +36,7 @@ export type ESSearchResponse<
|
|||
TDocument
|
||||
>;
|
||||
}
|
||||
: {}) &
|
||||
({
|
||||
: {}) & {
|
||||
hits: Omit<SearchResponse<TDocument>['hits'], 'total'> &
|
||||
(TOptions['restTotalHitsAsInt'] extends true
|
||||
? {
|
||||
|
@ -49,7 +48,7 @@ export type ESSearchResponse<
|
|||
relation: 'eq' | 'gte';
|
||||
};
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export interface ESFilter {
|
||||
[key: string]: {
|
||||
|
|
|
@ -27,20 +27,17 @@ export const validateConfigurationBlocks = (configurationBlocks: ConfigurationBl
|
|||
);
|
||||
}
|
||||
|
||||
const interfaceConfig = blockSchema.configs.reduce(
|
||||
(props, config) => {
|
||||
if (config.options) {
|
||||
props[config.id] = t.keyof(Object.fromEntries(
|
||||
config.options.map(opt => [opt.value, null])
|
||||
) as Record<string, null>);
|
||||
} else if (config.validation) {
|
||||
props[config.id] = validationMap[config.validation];
|
||||
}
|
||||
const interfaceConfig = blockSchema.configs.reduce((props, config) => {
|
||||
if (config.options) {
|
||||
props[config.id] = t.keyof(
|
||||
Object.fromEntries(config.options.map(opt => [opt.value, null])) as Record<string, null>
|
||||
);
|
||||
} else if (config.validation) {
|
||||
props[config.id] = validationMap[config.validation];
|
||||
}
|
||||
|
||||
return props;
|
||||
},
|
||||
{} as t.Props
|
||||
);
|
||||
return props;
|
||||
}, {} as t.Props);
|
||||
|
||||
const runtimeInterface = createConfigurationBlockInterface(
|
||||
t.literal(blockSchema.id),
|
||||
|
|
|
@ -13,9 +13,9 @@ export const OutputTypesArray = ['elasticsearch', 'logstash', 'kafka', 'redis'];
|
|||
// We can also pass in optional params to create spacific runtime checks that
|
||||
// can be used to validate blocs on the API and UI
|
||||
export const createConfigurationBlockInterface = (
|
||||
configType: t.LiteralType<string> | t.KeyofC<Record<string, null>> = t.keyof(Object.fromEntries(
|
||||
configBlockSchemas.map(s => [s.id, null])
|
||||
) as Record<string, null>),
|
||||
configType: t.LiteralType<string> | t.KeyofC<Record<string, null>> = t.keyof(
|
||||
Object.fromEntries(configBlockSchemas.map(s => [s.id, null])) as Record<string, null>
|
||||
),
|
||||
beatConfigInterface: t.Mixed = t.Dictionary
|
||||
) =>
|
||||
t.interface(
|
||||
|
|
|
@ -265,13 +265,11 @@ const withSuggestionsHidden = (state: AutocompleteFieldState) => ({
|
|||
selectedIndex: null,
|
||||
});
|
||||
|
||||
const FixedEuiFieldSearch: React.SFC<
|
||||
React.InputHTMLAttributes<HTMLInputElement> &
|
||||
EuiFieldSearchProps & {
|
||||
inputRef?: (element: HTMLInputElement | null) => void;
|
||||
onSearch: (value: string) => void;
|
||||
}
|
||||
> = EuiFieldSearch as any;
|
||||
const FixedEuiFieldSearch: React.SFC<React.InputHTMLAttributes<HTMLInputElement> &
|
||||
EuiFieldSearchProps & {
|
||||
inputRef?: (element: HTMLInputElement | null) => void;
|
||||
onSearch: (value: string) => void;
|
||||
}> = EuiFieldSearch as any;
|
||||
|
||||
const AutocompleteContainer = styled.div`
|
||||
position: relative;
|
||||
|
|
|
@ -53,16 +53,13 @@ export class BreadcrumbProvider extends Component<ComponentProps, ComponentState
|
|||
const { breadcrumbs } = this.state;
|
||||
|
||||
const context = {
|
||||
breadcrumbs: breadcrumbs.reduce(
|
||||
(crumbs, crumbStorageItem) => {
|
||||
if (crumbStorageItem.parents) {
|
||||
crumbs = crumbs.concat(crumbStorageItem.parents);
|
||||
}
|
||||
crumbs.push(crumbStorageItem.breadcrumb);
|
||||
return crumbs;
|
||||
},
|
||||
[] as Breadcrumb[]
|
||||
),
|
||||
breadcrumbs: breadcrumbs.reduce((crumbs, crumbStorageItem) => {
|
||||
if (crumbStorageItem.parents) {
|
||||
crumbs = crumbs.concat(crumbStorageItem.parents);
|
||||
}
|
||||
crumbs.push(crumbStorageItem.breadcrumb);
|
||||
return crumbs;
|
||||
}, [] as Breadcrumb[]),
|
||||
addCrumb: this.addCrumb,
|
||||
removeCrumb: this.removeCrumb,
|
||||
};
|
||||
|
|
|
@ -246,7 +246,10 @@ export const BeatsTableType: TableType = {
|
|||
name: i18n.translate('xpack.beatsManagement.beatsTable.typeLabel', {
|
||||
defaultMessage: 'Type',
|
||||
}),
|
||||
options: uniq(data.map(({ type }: { type: any }) => ({ value: type })), 'value'),
|
||||
options: uniq(
|
||||
data.map(({ type }: { type: any }) => ({ value: type })),
|
||||
'value'
|
||||
),
|
||||
},
|
||||
],
|
||||
}),
|
||||
|
|
|
@ -26,9 +26,9 @@ export class RestBeatsAdapter implements CMBeatsAdapter {
|
|||
|
||||
public async getBeatWithToken(enrollmentToken: string): Promise<CMBeat | null> {
|
||||
try {
|
||||
return (await this.REST.get<ReturnTypeGet<CMBeat>>(
|
||||
`/api/beats/agent/unknown/${enrollmentToken}`
|
||||
)).item;
|
||||
return (
|
||||
await this.REST.get<ReturnTypeGet<CMBeat>>(`/api/beats/agent/unknown/${enrollmentToken}`)
|
||||
).item;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
|
@ -59,16 +59,20 @@ export class RestBeatsAdapter implements CMBeatsAdapter {
|
|||
public async removeTagsFromBeats(
|
||||
removals: BeatsTagAssignment[]
|
||||
): Promise<ReturnTypeBulkAction['results']> {
|
||||
return (await this.REST.post<ReturnTypeBulkAction>(`/api/beats/agents_tags/removals`, {
|
||||
removals,
|
||||
})).results;
|
||||
return (
|
||||
await this.REST.post<ReturnTypeBulkAction>(`/api/beats/agents_tags/removals`, {
|
||||
removals,
|
||||
})
|
||||
).results;
|
||||
}
|
||||
|
||||
public async assignTagsToBeats(
|
||||
assignments: BeatsTagAssignment[]
|
||||
): Promise<ReturnTypeBulkAction['results']> {
|
||||
return (await this.REST.post<ReturnTypeBulkAction>(`/api/beats/agents_tags/assignments`, {
|
||||
assignments,
|
||||
})).results;
|
||||
return (
|
||||
await this.REST.post<ReturnTypeBulkAction>(`/api/beats/agents_tags/assignments`, {
|
||||
assignments,
|
||||
})
|
||||
).results;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,9 +20,9 @@ export class RestTagsAdapter implements CMTagsAdapter {
|
|||
|
||||
public async getTagsWithIds(tagIds: string[]): Promise<BeatTag[]> {
|
||||
try {
|
||||
return (await this.REST.get<ReturnTypeBulkGet<BeatTag>>(
|
||||
`/api/beats/tags/${uniq(tagIds).join(',')}`
|
||||
)).items;
|
||||
return (
|
||||
await this.REST.get<ReturnTypeBulkGet<BeatTag>>(`/api/beats/tags/${uniq(tagIds).join(',')}`)
|
||||
).items;
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
|
@ -37,9 +37,9 @@ export class RestTagsAdapter implements CMTagsAdapter {
|
|||
}
|
||||
|
||||
public async delete(tagIds: string[]): Promise<boolean> {
|
||||
return (await this.REST.delete<ReturnTypeBulkDelete>(
|
||||
`/api/beats/tags/${uniq(tagIds).join(',')}`
|
||||
)).success;
|
||||
return (
|
||||
await this.REST.delete<ReturnTypeBulkDelete>(`/api/beats/tags/${uniq(tagIds).join(',')}`)
|
||||
).success;
|
||||
}
|
||||
|
||||
public async upsertTag(tag: BeatTag): Promise<BeatTag | null> {
|
||||
|
@ -53,9 +53,11 @@ export class RestTagsAdapter implements CMTagsAdapter {
|
|||
|
||||
public async getAssignable(beats: CMBeat[]) {
|
||||
try {
|
||||
return (await this.REST.get<ReturnTypeBulkGet<BeatTag>>(
|
||||
`/api/beats/tags/assignable/${beats.map(beat => beat.id).join(',')}`
|
||||
)).items;
|
||||
return (
|
||||
await this.REST.get<ReturnTypeBulkGet<BeatTag>>(
|
||||
`/api/beats/tags/assignable/${beats.map(beat => beat.id).join(',')}`
|
||||
)
|
||||
).items;
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -12,12 +12,11 @@ export class RestTokensAdapter implements CMTokensAdapter {
|
|||
constructor(private readonly REST: RestAPIAdapter) {}
|
||||
|
||||
public async createEnrollmentTokens(numTokens: number = 1): Promise<string[]> {
|
||||
const results = (await this.REST.post<ReturnTypeBulkCreate<string>>(
|
||||
'/api/beats/enrollment_tokens',
|
||||
{
|
||||
const results = (
|
||||
await this.REST.post<ReturnTypeBulkCreate<string>>('/api/beats/enrollment_tokens', {
|
||||
num_tokens: numTokens,
|
||||
}
|
||||
)).results;
|
||||
})
|
||||
).results;
|
||||
return results.map(result => result.item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,11 @@ import { FrontendLibs } from '../types';
|
|||
|
||||
export function compose(basePath: string): FrontendLibs {
|
||||
const api = new NodeAxiosAPIAdapter('elastic', 'changeme', basePath);
|
||||
const esAdapter = new MemoryElasticsearchAdapter(() => true, () => '', []);
|
||||
const esAdapter = new MemoryElasticsearchAdapter(
|
||||
() => true,
|
||||
() => '',
|
||||
[]
|
||||
);
|
||||
const elasticsearchLib = new ElasticsearchLib(esAdapter);
|
||||
const configBlocks = new ConfigBlocksLib(
|
||||
new RestConfigBlocksAdapter(api),
|
||||
|
|
|
@ -40,15 +40,12 @@ export class CMTagsDomain {
|
|||
public async getNonConflictingTags(user: FrameworkUser, existingTagIds: string[]) {
|
||||
const tags = await this.adapter.getTagsWithIds(user, existingTagIds);
|
||||
const existingUniqueBlockTypes = uniq(
|
||||
tags.reduce(
|
||||
(existingUniqueTypes, tag) => {
|
||||
if (tag.hasConfigurationBlocksTypes) {
|
||||
existingUniqueTypes = existingUniqueTypes.concat(tag.hasConfigurationBlocksTypes);
|
||||
}
|
||||
return existingUniqueTypes;
|
||||
},
|
||||
[] as string[]
|
||||
)
|
||||
tags.reduce((existingUniqueTypes, tag) => {
|
||||
if (tag.hasConfigurationBlocksTypes) {
|
||||
existingUniqueTypes = existingUniqueTypes.concat(tag.hasConfigurationBlocksTypes);
|
||||
}
|
||||
return existingUniqueTypes;
|
||||
}, [] as string[])
|
||||
).filter(type => UNIQUENESS_ENFORCING_TYPES.includes(type));
|
||||
|
||||
const safeTags = await this.adapter.getWithoutConfigTypes(user, existingUniqueBlockTypes);
|
||||
|
|
|
@ -73,7 +73,10 @@ describe('assign_tags_to_beats', () => {
|
|||
authorization: 'loggedin',
|
||||
},
|
||||
payload: {
|
||||
assignments: [{ beatId: 'foo', tag: 'development' }, { beatId: 'bar', tag: 'development' }],
|
||||
assignments: [
|
||||
{ beatId: 'foo', tag: 'development' },
|
||||
{ beatId: 'bar', tag: 'development' },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -115,7 +118,10 @@ describe('assign_tags_to_beats', () => {
|
|||
authorization: 'loggedin',
|
||||
},
|
||||
payload: {
|
||||
assignments: [{ beatId: 'bar', tag: 'development' }, { beatId: 'bar', tag: 'production' }],
|
||||
assignments: [
|
||||
{ beatId: 'bar', tag: 'development' },
|
||||
{ beatId: 'bar', tag: 'production' },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -32,7 +32,10 @@ export function location(): ExpressionFunction<'location', null, {}, Promise<Ret
|
|||
const { latitude, longitude } = geoposition.coords;
|
||||
return resolve({
|
||||
type: 'datatable',
|
||||
columns: [{ name: 'latitude', type: 'number' }, { name: 'longitude', type: 'number' }],
|
||||
columns: [
|
||||
{ name: 'latitude', type: 'number' },
|
||||
{ name: 'longitude', type: 'number' },
|
||||
],
|
||||
rows: [{ latitude, longitude }],
|
||||
});
|
||||
}
|
||||
|
|
|
@ -14,7 +14,10 @@ describe('csv', () => {
|
|||
const fn = functionWrapper(csv);
|
||||
const expected = {
|
||||
type: 'datatable',
|
||||
columns: [{ name: 'name', type: 'string' }, { name: 'number', type: 'string' }],
|
||||
columns: [
|
||||
{ name: 'name', type: 'string' },
|
||||
{ name: 'number', type: 'string' },
|
||||
],
|
||||
rows: [
|
||||
{ name: 'one', number: '1' },
|
||||
{ name: 'two', number: '2' },
|
||||
|
|
|
@ -84,10 +84,16 @@ describe('getFlotAxisConfig', () => {
|
|||
describe('ticks', () => {
|
||||
it('adds a tick mark mapping for string columns', () => {
|
||||
let result = getFlotAxisConfig('x', true, { columns, ticks });
|
||||
expect(result.ticks).toEqual([[2, 'product1'], [1, 'product2']]);
|
||||
expect(result.ticks).toEqual([
|
||||
[2, 'product1'],
|
||||
[1, 'product2'],
|
||||
]);
|
||||
|
||||
result = getFlotAxisConfig('x', xAxisConfig, { columns, ticks });
|
||||
expect(result.ticks).toEqual([[2, 'product1'], [1, 'product2']]);
|
||||
expect(result.ticks).toEqual([
|
||||
[2, 'product1'],
|
||||
[1, 'product2'],
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -30,7 +30,12 @@ describe('getTickHash', () => {
|
|||
x: { type: 'number', role: 'dimension', expression: 'id' },
|
||||
y: { type: 'boolean', role: 'dimension', expression: 'running' },
|
||||
};
|
||||
const rows = [{ x: 1, y: true }, { x: 2, y: true }, { x: 1, y: false }, { x: 2, y: false }];
|
||||
const rows = [
|
||||
{ x: 1, y: true },
|
||||
{ x: 2, y: true },
|
||||
{ x: 1, y: false },
|
||||
{ x: 2, y: false },
|
||||
];
|
||||
|
||||
expect(getTickHash(columns, rows)).toEqual({
|
||||
x: { hash: {}, counter: 0 },
|
||||
|
|
|
@ -44,7 +44,10 @@ export function math(): ExpressionFunction<'math', Context, Arguments, number> {
|
|||
}
|
||||
|
||||
const mathContext = isDatatable(context)
|
||||
? pivotObjectArray(context.rows, context.columns.map(col => col.name))
|
||||
? pivotObjectArray(
|
||||
context.rows,
|
||||
context.columns.map(col => col.name)
|
||||
)
|
||||
: { value: context };
|
||||
|
||||
try {
|
||||
|
|
|
@ -187,7 +187,10 @@ export function pointseries(): ExpressionFunction<
|
|||
// Then compute that 1 value for each measure
|
||||
Object.values<DatatableRow[]>(measureKeys).forEach(valueRows => {
|
||||
const subtable = { type: 'datatable', columns: context.columns, rows: valueRows };
|
||||
const subScope = pivotObjectArray(subtable.rows, subtable.columns.map(col => col.name));
|
||||
const subScope = pivotObjectArray(
|
||||
subtable.rows,
|
||||
subtable.columns.map(col => col.name)
|
||||
);
|
||||
const measureValues = measureNames.map(measure => {
|
||||
try {
|
||||
const ev = evaluate(args[measure], subScope);
|
||||
|
|
|
@ -683,7 +683,14 @@ function init(plot) {
|
|||
const p4Y = radius * Math.sin(s.startAngle + s.angle / 1.5);
|
||||
const p5X = radius * Math.cos(s.startAngle + s.angle);
|
||||
const p5Y = radius * Math.sin(s.startAngle + s.angle);
|
||||
const arrPoly = [[0, 0], [p1X, p1Y], [p2X, p2Y], [p3X, p3Y], [p4X, p4Y], [p5X, p5Y]];
|
||||
const arrPoly = [
|
||||
[0, 0],
|
||||
[p1X, p1Y],
|
||||
[p2X, p2Y],
|
||||
[p3X, p3Y],
|
||||
[p4X, p4Y],
|
||||
[p5X, p5Y],
|
||||
];
|
||||
const arrPoint = [x, y];
|
||||
|
||||
// TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt?
|
||||
|
|
|
@ -14,7 +14,10 @@ const { Pie: strings } = ViewStrings;
|
|||
export const pie = () => ({
|
||||
name: 'pie',
|
||||
displayName: strings.getDisplayName(),
|
||||
modelArgs: [['color', { label: 'Slice Labels' }], ['size', { label: 'Slice Angles' }]],
|
||||
modelArgs: [
|
||||
['color', { label: 'Slice Labels' }],
|
||||
['size', { label: 'Slice Angles' }],
|
||||
],
|
||||
args: [
|
||||
{
|
||||
name: 'palette',
|
||||
|
|
|
@ -25,9 +25,6 @@ const mapDispatchToProps = dispatch => ({
|
|||
const branches = [branch(({ workpad }) => workpad == null, renderComponent(LoadWorkpad))];
|
||||
|
||||
export const ExportApp = compose(
|
||||
connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
),
|
||||
connect(mapStateToProps, mapDispatchToProps),
|
||||
...branches
|
||||
)(Component);
|
||||
|
|
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