Skip to content

Commit

Permalink
Add view events page
Browse files Browse the repository at this point in the history
Signed-off-by: Tyler Ohlsen <ohltyler@amazon.com>
  • Loading branch information
ohltyler committed Apr 24, 2023
1 parent de61732 commit 184eeec
Show file tree
Hide file tree
Showing 62 changed files with 1,932 additions and 46 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
1 change: 1 addition & 0 deletions src/plugins/ui_actions/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export {
visualizeFieldTrigger,
VISUALIZE_GEO_FIELD_TRIGGER,
visualizeGeoFieldTrigger,
OPEN_EVENTS_FLYOUT_TRIGGER,
} from './triggers';
export {
TriggerContextMapping,
Expand Down
1 change: 1 addition & 0 deletions src/plugins/ui_actions/public/triggers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ export * from './apply_filter_trigger';
export * from './visualize_field_trigger';
export * from './visualize_geo_field_trigger';
export * from './default_trigger';
export * from './open_events_flyout_trigger';
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

export const OPEN_EVENTS_FLYOUT_TRIGGER = 'OPEN_EVENTS_FLYOUT_TRIGGER';
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"]
}
4 changes: 2 additions & 2 deletions src/plugins/vis_augmenter/public/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ 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;
1 change: 1 addition & 0 deletions src/plugins/vis_augmenter/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export {
PointInTimeEvent,
PointInTimeEventsVisLayer,
isPointInTimeEventsVisLayer,
VisAugmenterEmbeddableConfig,
} from './types';

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

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 {
VisLayerTypes,
PointInTimeEventsVisLayer,
PluginResource,
PointInTimeEvent,
} from './types';

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;

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
): VisualizeEmbeddable => {
const mockTimeFilterService = timefilterServiceMock.createStartContract();
const mockTimeFilter = mockTimeFilterService.timefilter;
const mockVis = ({
type: {},
data: {},
uiState: {
on: jest.fn(),
},
} 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
): 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,
};
};

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,
};
};
32 changes: 28 additions & 4 deletions src/plugins/vis_augmenter/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,21 @@

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 } 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';

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface VisAugmenterSetup {}
Expand All @@ -18,12 +29,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,13 +46,24 @@ export class VisAugmenterPlugin

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

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

registerTriggersAndActions(core);

const savedAugmentVisLoader = createSavedAugmentVisLoader({
savedObjectsClient: core.savedObjects.client,
indexPatterns: data.indexPatterns,
Expand Down
21 changes: 20 additions & 1 deletion src/plugins/vis_augmenter/public/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,28 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { createGetterSetter } from '../../opensearch_dashboards_utils/common';
import { SavedObjectLoader } from '../../saved_objects/public';
import { EmbeddableStart } from '../../embeddable/public';
import { createGetterSetter } from '../../opensearch_dashboards_utils/public';
import { UiActionsStart } from '../../ui_actions/public';
import { DataPublicPluginStart } from '../../../plugins/data/public';
import { VisualizationsStart } from '../../visualizations/public';
import { CoreStart } from '../../../core/public';

export const [getSavedAugmentVisLoader, setSavedAugmentVisLoader] = createGetterSetter<
SavedObjectLoader
>('savedAugmentVisLoader');

export const [getUiActions, setUiActions] = createGetterSetter<UiActionsStart>('UIActions');

export const [getEmbeddable, setEmbeddable] = createGetterSetter<EmbeddableStart>('embeddable');

export const [getQueryService, setQueryService] = createGetterSetter<
DataPublicPluginStart['query']
>('Query');

export const [getVisualizations, setVisualizations] = createGetterSetter<VisualizationsStart>(
'visualizations'
);

export const [getCore, setCore] = createGetterSetter<CoreStart>('Core');
13 changes: 13 additions & 0 deletions src/plugins/vis_augmenter/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,16 @@ export const isPointInTimeEventsVisLayer = (obj: any) => {
export const isValidVisLayer = (obj: any) => {
return obj?.type in VisLayerTypes;
};

// TODO: clean these up to more clearly show what is happening or why these are needed.
// mostly all pertain to the view events flyout. If they apply multiple places, can leave as
// generic flags
export interface VisAugmenterEmbeddableConfig {
visLayerResourceIds?: string[];
showVisData?: boolean;
showEventData?: boolean;
showXAxis?: boolean;
fromDashboard?: boolean;
legendPosition?: string;
eventMarksFilled?: boolean;
}
43 changes: 43 additions & 0 deletions src/plugins/vis_augmenter/public/ui_actions_bootstrap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { CoreStart } from 'opensearch-dashboards/public';
import {
OpenEventsFlyoutAction,
ViewEventsOptionAction,
OPEN_EVENTS_FLYOUT_ACTION,
VIEW_EVENTS_OPTION_ACTION,
} from './view_events_flyout';
import { AugmentVisContext, openEventsFlyoutTrigger } from './view_events_flyout/triggers';
import { OPEN_EVENTS_FLYOUT_TRIGGER } from '../../ui_actions/public';
import { CONTEXT_MENU_TRIGGER, EmbeddableContext } from '../../embeddable/public';
import { getUiActions } from './services';

// Overriding the mappings defined in UIActions plugin so that
// the new trigger and action definitions resolve.
// This is a common pattern among internal Dashboards plugins.
declare module '../../ui_actions/public' {
export interface TriggerContextMapping {
[OPEN_EVENTS_FLYOUT_TRIGGER]: AugmentVisContext;
}

export interface ActionContextMapping {
[OPEN_EVENTS_FLYOUT_ACTION]: AugmentVisContext;
[VIEW_EVENTS_OPTION_ACTION]: EmbeddableContext;
}
}

export const registerTriggersAndActions = (core: CoreStart) => {
const openEventsFlyoutAction = new OpenEventsFlyoutAction(core);
const viewEventsOptionAction = new ViewEventsOptionAction(core);

getUiActions().registerAction(openEventsFlyoutAction);
getUiActions().registerAction(viewEventsOptionAction);
getUiActions().registerTrigger(openEventsFlyoutTrigger);
// Opening View Events flyout from the chart
getUiActions().addTriggerAction(OPEN_EVENTS_FLYOUT_TRIGGER, openEventsFlyoutAction);
// Opening View Events flyout from the context menu
getUiActions().addTriggerAction(CONTEXT_MENU_TRIGGER, viewEventsOptionAction);
};
Loading

0 comments on commit 184eeec

Please sign in to comment.