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 Mar 13, 2023
1 parent 797f73d commit 10dfac3
Show file tree
Hide file tree
Showing 55 changed files with 1,630 additions and 30 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"]
}
2 changes: 1 addition & 1 deletion src/plugins/vis_augmenter/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export {
SavedObjectOpenSearchDashboardsServicesWithAugmentVis,
} from './saved_augment_vis';

export { VisLayer, VisLayers, VisLayerTypes } from './types';
export { VisLayer, VisLayers, VisLayerTypes, PointInTimeEventsVisLayer } from './types';

export * from './expressions';
export * from './utils';
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,
};
};
34 changes: 30 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,26 @@ 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);

// registers the triggers & actions defined in this plugin
// also maps any triggers to possible actions
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');
42 changes: 42 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,42 @@
/*
* 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
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);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

export { OPEN_EVENTS_FLYOUT_ACTION, OpenEventsFlyoutAction } from './open_events_flyout_action';
export { VIEW_EVENTS_OPTION_ACTION, ViewEventsOptionAction } from './view_events_option_action';
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/
import React from 'react';
import { CoreStart } from 'src/core/public';
import { toMountPoint } from '../../../../opensearch_dashboards_react/public';
import { ViewEventsFlyout } from '../components';

interface Props {
core: CoreStart;
savedObjectId: string;
}

export async function openViewEventsFlyout(props: Props) {
const flyoutSession = props.core.overlays.openFlyout(
toMountPoint(
<ViewEventsFlyout
onClose={() => {
if (flyoutSession) {
flyoutSession.close();
}
}}
savedObjectId={props.savedObjectId}
/>
),
{
'data-test-subj': 'viewEventsFlyout',
ownFocus: true,
}
);
}
Loading

0 comments on commit 10dfac3

Please sign in to comment.