diff --git a/common/constants/shared.ts b/common/constants/shared.ts
index c24e76fcc0..c1f1993a6e 100644
--- a/common/constants/shared.ts
+++ b/common/constants/shared.ts
@@ -3,7 +3,6 @@
* SPDX-License-Identifier: Apache-2.0
*/
import CSS from 'csstype';
-import { IField } from '../../common/types/explorer';
// Client route
export const PPL_BASE = '/api/ppl';
@@ -27,6 +26,14 @@ export const observabilityID = 'observability-dashboards';
export const observabilityTitle = 'Observability';
export const observabilityPluginOrder = 6000;
+export const observabilityApplicationsID = 'observability-applications';
+export const observabilityApplicationsTitle = 'Application Analytics';
+export const observabilityApplicationsPluginOrder = 5090;
+
+export const observabilityEventsID = 'observability-events';
+export const observabilityEventsTitle = 'Event Analytics';
+export const observabilityEventsPluginOrder = 5091;
+
// Shared Constants
export const SQL_DOCUMENTATION_URL = 'https://opensearch.org/docs/latest/search-plugins/sql/index/';
export const PPL_DOCUMENTATION_URL =
diff --git a/public/components/app.tsx b/public/components/app.tsx
index d7b863eb00..d549233c0c 100644
--- a/public/components/app.tsx
+++ b/public/components/app.tsx
@@ -3,30 +3,24 @@
* SPDX-License-Identifier: Apache-2.0
*/
-import { I18nProvider } from '@osd/i18n/react';
import React from 'react';
import { Provider } from 'react-redux';
-import { HashRouter, Route, Switch } from 'react-router-dom';
+import { HashRouter } from 'react-router-dom';
import { QueryManager } from 'common/query_manager';
import { CoreStart } from '../../../../src/core/public';
-import { observabilityID, observabilityTitle } from '../../common/constants/shared';
import store from '../framework/redux/store';
import { AppPluginStartDependencies } from '../types';
-import { Home as ApplicationAnalyticsHome } from './application_analytics/home';
-import { Home as CustomPanelsHome } from './custom_panels/home';
-import { EventAnalytics } from './event_analytics';
-import { Main as NotebooksHome } from './notebooks/components/main';
-import { Home as TraceAnalyticsHome } from './trace_analytics/home';
-import { Home as MetricsHome } from './metrics/index';
+import { AppRoutesWrapper } from './routes_wrapper';
interface ObservabilityAppDeps {
- CoreStartProp: CoreStart;
- DepsStart: AppPluginStartDependencies;
+ coreStart: CoreStart;
+ depsStart: AppPluginStartDependencies;
pplService: any;
dslService: any;
savedObjects: any;
timestampUtils: any;
queryManager: QueryManager;
+ startPage?: String;
}
// for cypress to test redux store
@@ -35,133 +29,28 @@ if (window.Cypress) {
}
export const App = ({
- CoreStartProp,
- DepsStart,
+ coreStart,
+ depsStart,
pplService,
dslService,
savedObjects,
timestampUtils,
queryManager,
+ startPage,
}: ObservabilityAppDeps) => {
- const { chrome, http, notifications } = CoreStartProp;
- const parentBreadcrumb = {
- text: observabilityTitle,
- href: `${observabilityID}#/`,
- };
-
- const customPanelBreadcrumb = {
- text: 'Operational panels',
- href: '#/operational_panels/',
- };
-
return (
-
- <>
-
- {
- chrome.setBreadcrumbs([
- parentBreadcrumb,
- { text: 'Metrics analytics', href: '#/metrics_analytics/' },
- ]);
- return (
-
- );
- }}
- />
- {
- return (
-
- );
- }}
- />
- (
-
- )}
- />
- {
- chrome.setBreadcrumbs([parentBreadcrumb, customPanelBreadcrumb]);
- return (
-
- );
- }}
- />
- (
-
- )}
- />
- {
- return (
-
- );
- }}
- />
-
- >
-
+ {' '}
);
diff --git a/public/components/application_analytics/helpers/utils.tsx b/public/components/application_analytics/helpers/utils.tsx
index a9df996b16..c0539df8ba 100644
--- a/public/components/application_analytics/helpers/utils.tsx
+++ b/public/components/application_analytics/helpers/utils.tsx
@@ -41,6 +41,8 @@ import {
init as initPatterns,
remove as removePatterns,
} from '../../event_analytics/redux/slices/patterns_slice';
+import { from } from 'rxjs';
+import { mergeMap } from 'rxjs/operators';
// Name validation
export const isNameValid = (name: string, existingNames: string[]) => {
@@ -182,6 +184,10 @@ export const initializeTabData = async (dispatch: Dispatch, tabId: string,
});
};
+export const fetchAppsList = (http: HttpSetup) => {
+ return from(http.get(`${APP_ANALYTICS_API_PREFIX}/`)).pipe(mergeMap((res) => res.data));
+};
+
export const fetchPanelsVizIdList = async (http: HttpSetup, appPanelId: string) => {
return await http
.get(`${CUSTOM_PANELS_API_PREFIX}/panels/${appPanelId}`)
diff --git a/public/components/custom_panels/helpers/utils.tsx b/public/components/custom_panels/helpers/utils.tsx
index 0523391f23..a8d01f8f46 100644
--- a/public/components/custom_panels/helpers/utils.tsx
+++ b/public/components/custom_panels/helpers/utils.tsx
@@ -20,10 +20,14 @@ import { Visualization } from '../../visualizations/visualization';
import { getVizContainerProps } from '../../../components/visualizations/charts/helpers';
import { QueryManager } from '../../../../common/query_manager';
import { getDefaultVisConfig } from '../../event_analytics/utils';
+import { from } from 'rxjs';
+import { catchError, map } from 'rxjs/operators';
+import { HttpSetup } from '../../src/core/target/types/public';
/*
* "Utils" This file contains different reused functions in operational panels
*
+ * fetchPanelsList - Get list of Observability Panel from Custom Panels API
* isNameValid - Validates string to length > 0 and < 50
* convertDateTime - Converts input datetime string to required format
* mergeLayoutAndVisualizations - Function to merge current panel layout into the visualizations list
@@ -35,6 +39,16 @@ import { getDefaultVisConfig } from '../../event_analytics/utils';
* displayVisualization - Function to render the visualzation based of its type
*/
+export const fetchPanelsList = (http: HttpSetup) => {
+ return from(http.get(`${CUSTOM_PANELS_API_PREFIX}/panels`)).pipe(
+ map((res) => res.panels),
+ catchError((err) => {
+ console.error('Issue in fetching the operational panels', err.body.message);
+ return from([]);
+ })
+ );
+};
+
// Name validation 0>Name<=50
export const isNameValid = (name: string) => {
return name.length >= 50 || name.length === 0 ? false : true;
diff --git a/public/components/index.tsx b/public/components/index.tsx
index eec21a18b2..997167f88b 100644
--- a/public/components/index.tsx
+++ b/public/components/index.tsx
@@ -18,17 +18,19 @@ export const Observability = (
dslService: any,
savedObjects: any,
timestampUtils: any,
- queryManager: QueryManager
+ queryManager: QueryManager,
+ startPage?: String
) => {
ReactDOM.render(
,
AppMountParametersProp.element
);
diff --git a/public/plugin.ts b/public/plugin.ts
index 1e3189e578..10617843a7 100644
--- a/public/plugin.ts
+++ b/public/plugin.ts
@@ -3,8 +3,20 @@
* SPDX-License-Identifier: Apache-2.0
*/
-import { AppMountParameters, CoreSetup, CoreStart, Plugin } from '../../../src/core/public';
import {
+ AppMountParameters,
+ CoreSetup,
+ CoreStart,
+ DEFAULT_APP_CATEGORIES,
+ Plugin, PluginInitializerContext,
+} from '../../../src/core/public';
+import {
+ observabilityApplicationsID,
+ observabilityApplicationsPluginOrder,
+ observabilityApplicationsTitle,
+ observabilityEventsID,
+ observabilityEventsPluginOrder,
+ observabilityEventsTitle,
observabilityID,
observabilityPluginOrder,
observabilityTitle,
@@ -17,9 +29,19 @@ import { AppPluginStartDependencies, ObservabilitySetup, ObservabilityStart } fr
import { convertLegacyNotebooksUrl } from './components/notebooks/components/helpers/legacy_route_helpers';
import { convertLegacyTraceAnalyticsUrl } from './components/trace_analytics/components/common/legacy_route_helpers';
import { uiSettingsService } from '../common/utils';
+import { DashboardCreatorFn } from '../../../src/plugins/opensearch_dashboards_react/public/context/types';
+import { fetchPanelsList } from './components/custom_panels/helpers/utils';
+import { fetchAppsList } from './components/application_analytics/helpers/utils';
import { QueryManager } from '../common/query_manager';
+import { DashboardSetup } from '../../../src/plugins/dashboard/public';
+import { DashboardListItem } from '../../../src/plugins/dashboard/common/types';
+import { concat, from } from 'rxjs';
+import { catchError, map, mergeMap } from 'rxjs/operators';
+
export class ObservabilityPlugin implements Plugin {
- public setup(core: CoreSetup): ObservabilitySetup {
+ constructor(private initializerContext: PluginInitializerContext) {}
+
+ public setup(core: CoreSetup, { dashboard }: { dashboard: DashboardSetup }): ObservabilitySetup {
uiSettingsService.init(core.uiSettings, core.notifications);
// redirect legacy notebooks URL to current URL under observability
@@ -32,34 +54,114 @@ export class ObservabilityPlugin implements Plugin {
+ return from(fetchAppsList(core.http)).pipe(
+ map(convertAppAnalyticToDashboardListItem),
+ catchError((err) => {
+ console.error('Issue in fetching the app analytics list', err);
+ return from([]);
+ })
+ );
+ };
+
+ // Fetches all saved Custom Panels
+ const fetchObservabilityPanels = () => {
+ return from(fetchPanelsList(core.http)).pipe(
+ mergeMap((item) => item),
+ map(convertPanelToDashboardListItem),
+ catchError((err) => {
+ console.error('Issue in fetching the operational panels', err);
+ return from([]);
+ })
+ );
+ };
+
+ const convertPanelToDashboardListItem = (item: any): DashboardListItem => {
+ return {
+ id: item.id,
+ title: item.name,
+ type: 'Observability Panel',
+ description: '...',
+ url: `observability-dashboards#/operational_panels/${item.id}`,
+ listType: 'observabiliity-panel',
+ };
+ };
+
+ const convertAppAnalyticToDashboardListItem = (item: any): DashboardListItem => {
+ return {
+ id: item.id,
+ title: item.name,
+ type: 'Observability Application',
+ description: item.description,
+ url: `observability-dashboards#/application_analytics/${item.id}`,
+ listType: 'observability-application',
+ };
+ };
+
+ const id: string = this.initializerContext.opaqueId.description!;
+
+ const dashboardAppAnalytics = fetchApplicationAnalytics();
+ const dashboardObservabilityPanels = fetchObservabilityPanels();
+ const combinedDashboardList = concat(dashboardAppAnalytics, dashboardObservabilityPanels);
+
+ const createAppAnalytics: DashboardCreatorFn = () => {
+ window.location = core.http.basePath.prepend(
+ '/app/observability-dashboards#/application_analytics/create'
+ );
+ };
+
+ dashboard.registerDashboardListSource(id, () => combinedDashboardList);
+ dashboard.registerDashboardItemCreator({
+ id: 'observaility-application',
+ defaultText: 'Analytics Application',
+ creatorFn: createAppAnalytics,
+ });
+
+ const appMountWithStartPage = (startPage?: string) => async (params: AppMountParameters) => {
+ const { Observability } = await import('./components/index');
+ const [coreStart, depsStart] = await core.getStartServices();
+ const pplService = new PPLService(coreStart.http);
+ const dslService = new DSLService(coreStart.http);
+ const savedObjects = new SavedObjects(coreStart.http);
+ const timestampUtils = new TimestampUtils(dslService);
+ const qm = new QueryManager();
+
+ return Observability(
+ coreStart,
+ depsStart as AppPluginStartDependencies,
+ params,
+ pplService,
+ dslService,
+ savedObjects,
+ timestampUtils,
+ qm,
+ startPage
+ );
+ };
+
+ core.application.register({
+ id: observabilityApplicationsID,
+ title: observabilityApplicationsTitle,
+ category: DEFAULT_APP_CATEGORIES.observability,
+ order: observabilityApplicationsPluginOrder,
+ mount: appMountWithStartPage('/application_analytics'),
+ });
+
+ core.application.register({
+ id: observabilityEventsID,
+ title: observabilityEventsTitle,
+ category: DEFAULT_APP_CATEGORIES.observability,
+ order: observabilityEventsPluginOrder,
+ mount: appMountWithStartPage('/event_analytics'),
+ });
+
core.application.register({
id: observabilityID,
title: observabilityTitle,
- category: {
- id: 'opensearch',
- label: 'OpenSearch Plugins',
- order: 2000,
- },
+ category: DEFAULT_APP_CATEGORIES.plugins,
order: observabilityPluginOrder,
- async mount(params: AppMountParameters) {
- const { Observability } = await import('./components/index');
- const [coreStart, depsStart] = await core.getStartServices();
- const pplService = new PPLService(coreStart.http);
- const dslService = new DSLService(coreStart.http);
- const savedObjects = new SavedObjects(coreStart.http);
- const timestampUtils = new TimestampUtils(dslService, pplService);
- const qm = new QueryManager();
- return Observability(
- coreStart,
- depsStart as AppPluginStartDependencies,
- params,
- pplService,
- dslService,
- savedObjects,
- timestampUtils,
- qm
- );
- },
+ mount: appMountWithStartPage(),
});
// Return methods that should be available to other plugins