Skip to content

Commit

Permalink
[Feature Anywhere] Add view events flyout (#3415)
Browse files Browse the repository at this point in the history
Signed-off-by: Tyler Ohlsen <ohltyler@amazon.com>
  • Loading branch information
ohltyler authored May 31, 2023
1 parent 66070aa commit 319b5a2
Show file tree
Hide file tree
Showing 66 changed files with 2,324 additions and 197 deletions.
4 changes: 4 additions & 0 deletions src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ interface Props {
SavedObjectFinder: React.ComponentType<any>;
stateTransfer?: EmbeddableStateTransfer;
hideHeader?: boolean;
hasBorder?: boolean;
hasShadow?: boolean;
}

interface State {
Expand Down Expand Up @@ -234,6 +236,8 @@ export class EmbeddablePanel extends React.Component<Props, State> {
paddingSize="none"
role="figure"
aria-labelledby={headerId}
hasBorder={this.props.hasBorder}
hasShadow={this.props.hasShadow}
>
{!this.props.hideHeader && (
<PanelHeader
Expand Down
13 changes: 12 additions & 1 deletion src/plugins/embeddable/public/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,12 @@ export interface EmbeddableStart extends PersistableState<EmbeddableInput> {
getStateTransfer: (history?: ScopedHistory) => EmbeddableStateTransfer;
}

export type EmbeddablePanelHOC = React.FC<{ embeddable: IEmbeddable; hideHeader?: boolean }>;
export type EmbeddablePanelHOC = React.FC<{
embeddable: IEmbeddable;
hideHeader?: boolean;
hasBorder?: boolean;
hasShadow?: boolean;
}>;

export class EmbeddablePublicPlugin implements Plugin<EmbeddableSetup, EmbeddableStart> {
private readonly embeddableFactoryDefinitions: Map<
Expand Down Expand Up @@ -168,12 +173,18 @@ export class EmbeddablePublicPlugin implements Plugin<EmbeddableSetup, Embeddabl
const getEmbeddablePanelHoc = (stateTransfer?: EmbeddableStateTransfer) => ({
embeddable,
hideHeader,
hasBorder,
hasShadow,
}: {
embeddable: IEmbeddable;
hideHeader?: boolean;
hasBorder?: boolean;
hasShadow?: boolean;
}) => (
<EmbeddablePanel
hideHeader={hideHeader}
hasBorder={hasBorder}
hasShadow={hasShadow}
embeddable={embeddable}
stateTransfer={stateTransfer ? stateTransfer : this.outgoingOnlyStateTransfer}
getActions={uiActions.getTriggerCompatibleActions}
Expand Down
11 changes: 10 additions & 1 deletion src/plugins/vis_augmenter/opensearch_dashboards.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,14 @@
"version": "opensearchDashboards",
"server": true,
"ui": true,
"requiredPlugins": ["data", "savedObjects", "opensearchDashboardsUtils", "expressions"]
"requiredPlugins": [
"data",
"savedObjects",
"opensearchDashboardsUtils",
"expressions",
"visualizations",
"uiActions",
"embeddable"
],
"requiredBundles": ["opensearchDashboardsReact"]
}
5 changes: 2 additions & 3 deletions src/plugins/vis_augmenter/public/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@
*/

export const VIS_LAYER_COLUMN_TYPE = 'vis_layer';
// TODO: replace with a value imported from OUI
export const EVENT_COLOR = 'red';
export const HOVER_PARAM = 'HOVER';
export const EVENT_MARK_SIZE = 100;
export const EVENT_MARK_SIZE_ENLARGED = 140;
export const EVENT_MARK_SIZE = 40;
export const EVENT_MARK_SIZE_ENLARGED = 80;
export const EVENT_MARK_SHAPE = 'triangle-up';
export const EVENT_TIMELINE_HEIGHT = 25;
export const EVENT_TOOLTIP_CENTER_ON_MARK = 5;
4 changes: 4 additions & 0 deletions src/plugins/vis_augmenter/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,12 @@ export {
PointInTimeEventsVisLayer,
isPointInTimeEventsVisLayer,
isVisLayerWithError,
VisAugmenterEmbeddableConfig,
VisFlyoutContext,
} from './types';

export { AugmentVisContext } from './ui_actions_bootstrap';

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

import { get } from 'lodash';
import { VisualizeEmbeddable, Vis } from '../../visualizations/public';
import { ErrorEmbeddable } from '../../embeddable/public';
// eslint-disable-next-line @osd/eslint/no-restricted-paths
import { timefilterServiceMock } from '../../data/public/query/timefilter/timefilter_service.mock';
import { EventVisEmbeddableItem } from './view_events_flyout';
import {
VisLayer,
VisLayerTypes,
VisLayerErrorTypes,
PointInTimeEventsVisLayer,
PluginResource,
PointInTimeEvent,
} from './types';
import { AggConfigs, AggTypesRegistryStart, IndexPattern } from '../../data/common';
import { mockAggTypesRegistry } from '../../data/common/search/aggs/test_helpers';

export const VALID_CONFIG_STATES = [
{
enabled: true,
type: 'max',
params: {},
schema: 'metric',
},
{
enabled: true,
type: 'date_histogram',
params: {},
schema: 'segment',
},
];

export const STUB_INDEX_PATTERN_WITH_FIELDS = {
id: '1234',
title: 'logstash-*',
fields: [
{
name: 'response',
type: 'number',
esTypes: ['integer'],
aggregatable: true,
filterable: true,
searchable: true,
},
],
} as IndexPattern;

export const TYPES_REGISTRY: AggTypesRegistryStart = mockAggTypesRegistry();

export const VALID_AGGS = new AggConfigs(STUB_INDEX_PATTERN_WITH_FIELDS, VALID_CONFIG_STATES, {
typesRegistry: TYPES_REGISTRY,
});

export const VALID_VIS = ({
type: {},
uiState: {
on: jest.fn(),
},
params: {
type: 'line',
seriesParams: [
{
type: 'line',
},
],
categoryAxes: [
{
position: 'bottom',
},
],
},
data: {
aggs: VALID_AGGS,
},
} as unknown) as Vis;

const SAVED_OBJ_ID = 'test-saved-obj-id';
const VIS_TITLE = 'test-vis-title';
const ORIGIN_PLUGIN = 'test-plugin';
const PLUGIN_RESOURCE = {
type: 'test-type',
id: 'test-resource-id',
name: 'test-resource-name',
urlPath: 'test-url-path',
} as PluginResource;
const EVENT_COUNT = 3;
const ERROR_MESSAGE = 'test-error-message';

export const createPluginResource = (
type: string = PLUGIN_RESOURCE.type,
id: string = PLUGIN_RESOURCE.id,
name: string = PLUGIN_RESOURCE.name,
urlPath: string = PLUGIN_RESOURCE.urlPath
): PluginResource => {
return {
type,
id,
name,
urlPath,
};
};

export const createMockErrorEmbeddable = (): ErrorEmbeddable => {
return new ErrorEmbeddable('Oh no something has gone wrong', { id: ' 404' });
};

export const createMockVisEmbeddable = (
savedObjectId: string = SAVED_OBJ_ID,
title: string = VIS_TITLE,
validVis: boolean = true
): VisualizeEmbeddable => {
const mockTimeFilterService = timefilterServiceMock.createStartContract();
const mockTimeFilter = mockTimeFilterService.timefilter;
const mockVis = validVis
? VALID_VIS
: (({
type: {},
data: {},
uiState: {
on: jest.fn(),
},
params: {
type: 'line',
seriesParams: [],
},
} as unknown) as Vis);
const mockDeps = {
start: jest.fn(),
};
const mockConfiguration = {
vis: mockVis,
editPath: 'test-edit-path',
editUrl: 'test-edit-url',
editable: true,
deps: mockDeps,
};
const mockVisualizeInput = { id: 'test-id', savedObjectId };

const mockVisEmbeddable = new VisualizeEmbeddable(
mockTimeFilter,
mockConfiguration,
mockVisualizeInput
);
mockVisEmbeddable.getTitle = () => title;
return mockVisEmbeddable;
};

export const createPointInTimeEventsVisLayer = (
originPlugin: string = ORIGIN_PLUGIN,
pluginResource: PluginResource = PLUGIN_RESOURCE,
eventCount: number = EVENT_COUNT,
error: boolean = false,
errorMessage: string = ERROR_MESSAGE
): PointInTimeEventsVisLayer => {
const events = [] as PointInTimeEvent[];
for (let i = 0; i < eventCount; i++) {
events.push({
timestamp: i,
metadata: {
pluginResourceId: pluginResource.id,
},
} as PointInTimeEvent);
}
return {
originPlugin,
type: VisLayerTypes.PointInTimeEvents,
pluginResource,
events,
error: error
? {
type: VisLayerErrorTypes.FETCH_FAILURE,
message: errorMessage,
}
: undefined,
};
};

export const createMockEventVisEmbeddableItem = (
savedObjectId: string = SAVED_OBJ_ID,
title: string = VIS_TITLE,
originPlugin: string = ORIGIN_PLUGIN,
pluginResource: PluginResource = PLUGIN_RESOURCE,
eventCount: number = EVENT_COUNT
): EventVisEmbeddableItem => {
const visLayer = createPointInTimeEventsVisLayer(originPlugin, pluginResource, eventCount);
const embeddable = createMockVisEmbeddable(savedObjectId, title);
return {
visLayer,
embeddable,
};
};

export const createVisLayer = (
type: any,
error: boolean = false,
errorMessage: string = 'some-error-message',
resource?: {
type?: string;
id?: string;
name?: string;
urlPath?: string;
}
): VisLayer => {
return {
type,
originPlugin: 'test-plugin',
pluginResource: {
type: get(resource, 'type', 'test-resource-type'),
id: get(resource, 'id', 'test-resource-id'),
name: get(resource, 'name', 'test-resource-name'),
urlPath: get(resource, 'urlPath', 'test-resource-url-path'),
},
error: error
? {
type: VisLayerErrorTypes.FETCH_FAILURE,
message: errorMessage,
}
: undefined,
};
};
36 changes: 31 additions & 5 deletions src/plugins/vis_augmenter/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,22 @@

import { ExpressionsSetup } from '../../expressions/public';
import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from '../../../core/public';
import { DataPublicPluginSetup, DataPublicPluginStart } from '../../data/public';
import { visLayers } from './expressions';
import { setSavedAugmentVisLoader, setUISettings } from './services';
import { createSavedAugmentVisLoader, SavedAugmentVisLoader } from './saved_augment_vis';
import { registerTriggersAndActions } from './ui_actions_bootstrap';
import { UiActionsStart } from '../../ui_actions/public';
import {
setUiActions,
setEmbeddable,
setQueryService,
setVisualizations,
setCore,
} from './services';
import { EmbeddableStart } from '../../embeddable/public';
import { DataPublicPluginStart } from '../../data/public';
import { VisualizationsStart } from '../../visualizations/public';
import { VIEW_EVENTS_FLYOUT_STATE, setFlyoutState } from './view_events_flyout';

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface VisAugmenterSetup {}
Expand All @@ -18,12 +30,14 @@ export interface VisAugmenterStart {
}

export interface VisAugmenterSetupDeps {
data: DataPublicPluginSetup;
expressions: ExpressionsSetup;
}

export interface VisAugmenterStartDeps {
uiActions: UiActionsStart;
embeddable: EmbeddableStart;
data: DataPublicPluginStart;
visualizations: VisualizationsStart;
}

export class VisAugmenterPlugin
Expand All @@ -33,14 +47,26 @@ export class VisAugmenterPlugin

public setup(
core: CoreSetup<VisAugmenterStartDeps, VisAugmenterStart>,
{ data, expressions }: VisAugmenterSetupDeps
{ expressions }: VisAugmenterSetupDeps
): VisAugmenterSetup {
expressions.registerType(visLayers);
setUISettings(core.uiSettings);
return {};
}

public start(core: CoreStart, { data }: VisAugmenterStartDeps): VisAugmenterStart {
setUISettings(core.uiSettings);
public start(
core: CoreStart,
{ uiActions, embeddable, data, visualizations }: VisAugmenterStartDeps
): VisAugmenterStart {
setUiActions(uiActions);
setEmbeddable(embeddable);
setQueryService(data.query);
setVisualizations(visualizations);
setCore(core);
setFlyoutState(VIEW_EVENTS_FLYOUT_STATE.CLOSED);

registerTriggersAndActions(core);

const savedAugmentVisLoader = createSavedAugmentVisLoader({
savedObjectsClient: core.savedObjects.client,
indexPatterns: data.indexPatterns,
Expand Down
Loading

0 comments on commit 319b5a2

Please sign in to comment.