Skip to content

Commit

Permalink
Collect VisLayers in VisualizeEmbeddable render flow
Browse files Browse the repository at this point in the history
Signed-off-by: Tyler Ohlsen <ohltyler@amazon.com>
  • Loading branch information
ohltyler committed Feb 9, 2023
1 parent eeed599 commit d061adf
Show file tree
Hide file tree
Showing 17 changed files with 276 additions and 72 deletions.
60 changes: 0 additions & 60 deletions src/plugins/vis_augmenter/common/types.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/plugins/vis_augmenter/public/expressions/vis_layers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import { ExpressionTypeDefinition } from '../../../expressions';
import { VisLayers } from '../../common';
import { VisLayers } from '../';

const name = 'vis_layers';

Expand Down
12 changes: 11 additions & 1 deletion src/plugins/vis_augmenter/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,14 @@ export {
SavedObjectOpenSearchDashboardsServicesWithAugmentVis,
} from './saved_augment_vis';

export { ISavedAugmentVis, VisLayerExpressionFn, AugmentVisSavedObject } from './types';
export {
ISavedAugmentVis,
VisLayerExpressionFn,
AugmentVisSavedObject,
VisLayerFunctionDefinition,
VisLayer,
VisLayers,
} from './types';

export * from './expressions';
export * from './utils';
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { VisLayerExpressionFn } from '../types';
import { VisLayerTypes } from '../../common';
import { VisLayerExpressionFn, VisLayerTypes } from '../types';
import {
createSavedAugmentVisLoader,
SavedObjectOpenSearchDashboardsServicesWithAugmentVis,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
SavedObjectOpenSearchDashboardsServices,
} from '../../../saved_objects/public';
import { createSavedAugmentVisClass } from './_saved_augment_vis';
import { VisLayerTypes } from '../../common';
import { VisLayerTypes } from '../types';

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface SavedObjectOpenSearchDashboardsServicesWithAugmentVis
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { extractReferences, injectReferences } from './saved_augment_vis_references';
import {
extractReferences,
injectReferences,
VIS_REFERENCE_NAME,
} from './saved_augment_vis_references';
import { AugmentVisSavedObject } from '../types';
import { VIS_REFERENCE_NAME } from './saved_augment_vis_references';

describe('extractReferences()', () => {
test('extracts nothing if visId is null', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ import { VIS_REFERENCE_NAME } from '../saved_augment_vis_references';

const pluginResourceId = 'test-plugin-resource-id';
const visId = 'test-vis-id';
const title = 'test-title';
const version = 1;

export const generateAugmentVisSavedObject = (idArg: string, exprFnArg: VisLayerExpressionFn) => {
return {
id: idArg,
title,
pluginResourceId,
visLayerExpressionFn: exprFnArg,
VIS_REFERENCE_NAME,
Expand Down
57 changes: 56 additions & 1 deletion src/plugins/vis_augmenter/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,54 @@
*/

import { SavedObject } from '../../saved_objects/public';
import { VisLayerTypes } from '../common';
import { ExpressionFunctionDefinition } from '../../expressions';

export enum VisLayerTypes {
PointInTimeEvents = 'PointInTimeEvents',
}

export type PluginResourceType = string;

export interface PluginResource {
type: PluginResourceType;
id: string;
name: string;
urlPath: string;
}

export interface VisLayer {
type: keyof typeof VisLayerTypes;
originPlugin: string;
pluginResource: PluginResource;
}

export type VisLayers = VisLayer[];

export interface EventMetadata {
pluginResourceId: string;
tooltip?: string;
}

export interface PointInTimeEvent {
timestamp: number;
metadata: EventMetadata;
}

export interface PointInTimeEventsVisLayer extends VisLayer {
events: PointInTimeEvent[];
}

export const isPointInTimeEventsVisLayer = (obj: any) => {
return obj?.type === VisLayerTypes.PointInTimeEvents;
};

export const isValidVisLayer = (obj: any) => {
return obj?.type in VisLayerTypes;
};

export interface ISavedAugmentVis {
id?: string;
title: string;
description?: string;
pluginResourceId: string;
visName?: string;
Expand All @@ -24,3 +68,14 @@ export interface VisLayerExpressionFn {
}

export interface AugmentVisSavedObject extends SavedObject, ISavedAugmentVis {}

export interface VisLayerResponseValue {
visLayers: object;
}

export type VisLayerFunctionDefinition = ExpressionFunctionDefinition<
string,
VisLayerResponseValue,
any,
Promise<VisLayerResponseValue>
>;
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
* SPDX-License-Identifier: Apache-2.0
*/

export * from './types';
export * from './utils';
80 changes: 80 additions & 0 deletions src/plugins/vis_augmenter/public/utils/utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { Vis } from '../../../visualizations/public';
import { buildPipelineFromAugmentVisSavedObjs, isEligibleForVisLayers } from './utils';
import { VisLayerTypes, ISavedAugmentVis } from '../types';

describe('utils', () => {
// TODO: redo / update this test suite when eligibility is finalized.
// Tracked in https://github.com/opensearch-project/OpenSearch-Dashboards/issues/3268
describe('isEligibleForVisLayers', () => {
it('vis is ineligible with invalid type', async () => {
const vis = ({
params: {
type: 'not-line',
},
} as unknown) as Vis;
expect(isEligibleForVisLayers(vis)).toEqual(false);
});
it('vis is eligible with valid type', async () => {
const vis = ({
params: {
type: 'line',
},
} as unknown) as Vis;
expect(isEligibleForVisLayers(vis)).toEqual(true);
});
});

describe('getAugmentVisSavedObjs', () => {
// TODO: add tests after saved obj PR tests are added; can use
// them for instantiating mock saved obj loader
});

describe('buildPipelineFromAugmentVisSavedObjs', () => {
const obj1 = {
title: 'obj1',
pluginResourceId: 'obj-1-resource-id',
visLayerExpressionFn: {
type: VisLayerTypes.PointInTimeEvents,
name: 'fn-1',
args: {
arg1: 'value-1',
},
},
} as ISavedAugmentVis;
const obj2 = {
title: 'obj2',
pluginResourceId: 'obj-2-resource-id',
visLayerExpressionFn: {
type: VisLayerTypes.PointInTimeEvents,
name: 'fn-2',
args: {
arg2: 'value-2',
},
},
} as ISavedAugmentVis;
it('catches error with empty array', async () => {
try {
buildPipelineFromAugmentVisSavedObjs([]);
} catch (e: any) {
expect(
e.message.includes(
'Expression function from augment-vis saved objects could not be generated'
)
);
}
});
it('builds with one saved obj', async () => {
const str = buildPipelineFromAugmentVisSavedObjs([obj1]);
expect(str).toEqual('fn-1 arg1="value-1"');
});
it('builds with multiple saved objs', async () => {
const str = buildPipelineFromAugmentVisSavedObjs([obj1, obj2]);
expect(str).toEqual(`fn-1 arg1="value-1"\n| fn-2 arg2="value-2"`);
});
});
});
55 changes: 55 additions & 0 deletions src/plugins/vis_augmenter/public/utils/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { get } from 'lodash';
import { Vis } from '../../../visualizations/public';
import {
formatExpression,
buildExpressionFunction,
buildExpression,
ExpressionAstFunctionBuilder,
} from '../../../../plugins/expressions/public';
import { ISavedAugmentVis, SavedAugmentVisLoader, VisLayerFunctionDefinition } from '../';

// TODO: provide a deeper eligibility check.
// Tracked in https://github.com/opensearch-project/OpenSearch-Dashboards/issues/3268
export const isEligibleForVisLayers = (vis: Vis): boolean => {
return vis.params.type === 'line';
};

export const getAugmentVisSavedObjs = async (
visId: string | undefined,
loader: SavedAugmentVisLoader | undefined
): Promise<ISavedAugmentVis[]> => {
try {
const resp = await loader?.findAll();
const allSavedObjects = (get(resp, 'hits', []) as any[]) as ISavedAugmentVis[];
return allSavedObjects.filter((hit: ISavedAugmentVis) => hit.visId === visId);
} catch (e) {
// console.error('Unable to search for augment-vis saved objects: ', e);
return [] as ISavedAugmentVis[];
}
};

export const buildPipelineFromAugmentVisSavedObjs = (objs: ISavedAugmentVis[]): string => {
const visLayerExpressionFns = [] as Array<
ExpressionAstFunctionBuilder<VisLayerFunctionDefinition>
>;

try {
objs.forEach((obj: ISavedAugmentVis) => {
visLayerExpressionFns.push(
buildExpressionFunction<VisLayerFunctionDefinition>(
obj.visLayerExpressionFn.name,
obj.visLayerExpressionFn.args
)
);
});
const ast = buildExpression(visLayerExpressionFns).toAst();
return formatExpression(ast);
} catch (e) {
throw new Error('Expression function from augment-vis saved objects could not be generated');
}
};
2 changes: 1 addition & 1 deletion src/plugins/visualizations/opensearch_dashboards.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
"ui": true,
"requiredPlugins": ["data", "expressions", "uiActions", "embeddable", "inspector", "dashboard"],
"optionalPlugins": ["usageCollection"],
"requiredBundles": ["opensearchDashboardsUtils", "discover", "savedObjects"]
"requiredBundles": ["opensearchDashboardsUtils", "discover", "savedObjects", "visAugmenter"]
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import { IContainer, ErrorEmbeddable } from '../../../embeddable/public';
import { DisabledLabEmbeddable } from './disabled_lab_embeddable';
import {
getSavedVisualizationsLoader,
getSavedAugmentVisLoader,
getUISettings,
getHttp,
getTimeFilter,
Expand Down Expand Up @@ -88,6 +89,8 @@ export const createVisEmbeddableFromObject = (deps: VisualizeEmbeddableFactoryDe

const editable = getCapabilities().visualize.save as boolean;

const savedAugmentVisLoader = getSavedAugmentVisLoader();

return new VisualizeEmbeddable(
getTimeFilter(),
{
Expand All @@ -101,6 +104,7 @@ export const createVisEmbeddableFromObject = (deps: VisualizeEmbeddableFactoryDe
input,
attributeService,
savedVisualizationsLoader,
savedAugmentVisLoader,
parent
);
} catch (e) {
Expand Down
Loading

0 comments on commit d061adf

Please sign in to comment.