From 36df057ecb9bbbc123e264601b145a136538ee76 Mon Sep 17 00:00:00 2001 From: Dan Dong Date: Mon, 5 Aug 2024 15:04:42 -0700 Subject: [PATCH] Added new cards Signed-off-by: Dan Dong --- public/components/overview/card_configs.tsx | 111 ++++++++++++ public/components/overview/home.tsx | 185 +++++++++----------- 2 files changed, 193 insertions(+), 103 deletions(-) create mode 100644 public/components/overview/card_configs.tsx diff --git a/public/components/overview/card_configs.tsx b/public/components/overview/card_configs.tsx new file mode 100644 index 0000000000..cab4c01dec --- /dev/null +++ b/public/components/overview/card_configs.tsx @@ -0,0 +1,111 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { i18n } from '@osd/i18n'; + +// Plugin URLs +const gettingStartedURL = 'observability-gettingStarted'; +const discoverURL = 'data-explorer/discover'; +const metricsURL = 'observability-metrics'; +const tracesURL = 'observability-traces-nav#/traces'; +const servicesURL = 'observability-services-nav#/services'; +const alertsURL = 'alerting'; +const anomalyDetectionURL = 'anomaly-detection-dashboards'; + +export interface GettingStartedConfig { + id: string; + order: number; + title: string; + description: string; + footer: string; + url: string; +} + +export const GETTING_STARTED_CONFIG: GettingStartedConfig = { + id: 'getting_started', + order: 1, + title: i18n.translate('observability.overview.card.gettingStarted.title', { + defaultMessage: 'Add your data', + }), + description: 'Get started collecting and analyzing data.', + footer: 'with Getting Started Guide', + url: gettingStartedURL, +}; + +const DISCOVER_CONFIG: GettingStartedConfig = { + id: 'discover', + order: 2, + title: i18n.translate('observability.overview.card.discover.title', { + defaultMessage: 'Discover insights', + }), + description: 'Uncover insights with raw data exploration.', + footer: 'with Discover', + url: discoverURL, +}; + +const METRICS_CONFIG: GettingStartedConfig = { + id: 'metrics', + order: 3, + title: i18n.translate('observability.overview.card.metrics.title', { + defaultMessage: 'Metrics', + }), + description: 'Transform logs into actionable visualizations with metrics extraction.', + footer: 'with Metrics', + url: metricsURL, +}; + +const TRACES_CONFIG: GettingStartedConfig = { + id: 'traces', + order: 4, + title: i18n.translate('observability.overview.card.traces.title', { + defaultMessage: 'Traces', + }), + description: 'Unveil performance bottlenecks with event flow visualization.', + footer: 'with Traces', + url: tracesURL, +}; + +const SERVICES_CONFIG: GettingStartedConfig = { + id: 'services', + order: 5, + title: i18n.translate('observability.overview.card.services.title', { + defaultMessage: 'Services', + }), + description: 'Unveil performance bottlenecks with event flow visualization.', + footer: 'with Services', + url: servicesURL, +}; + +const ALERTS_CONFIG: GettingStartedConfig = { + id: 'alerts', + order: 6, + title: i18n.translate('observability.overview.card.alerts.title', { + defaultMessage: 'Alerts', + }), + description: 'Unveil performance bottlenecks with event flow visualization.', + footer: 'with Alerts', + url: alertsURL, +}; + +const ANOMALY_CONFIG: GettingStartedConfig = { + id: 'anomaly', + order: 7, + title: i18n.translate('observability.overview.card.anomaly.title', { + defaultMessage: 'Anomaly Detection', + }), + description: 'Unveil performance bottlenecks with event flow visualization.', + footer: 'with Anomaly Detection', + url: anomalyDetectionURL, +}; + +export const cardConfigs = [ + GETTING_STARTED_CONFIG, + DISCOVER_CONFIG, + METRICS_CONFIG, + TRACES_CONFIG, + SERVICES_CONFIG, + ALERTS_CONFIG, + ANOMALY_CONFIG, +]; diff --git a/public/components/overview/home.tsx b/public/components/overview/home.tsx index 7802dbf494..b96db68df1 100644 --- a/public/components/overview/home.tsx +++ b/public/components/overview/home.tsx @@ -6,18 +6,16 @@ import React, { useEffect, useState } from 'react'; import { HashRouter, RouteComponentProps, Switch, Route } from 'react-router-dom'; import { EuiSelect, EuiText } from '@elastic/eui'; -import { i18n } from '@osd/i18n'; import { TraceAnalyticsCoreDeps } from '../trace_analytics/home'; import { ChromeBreadcrumb } from '../../../../../src/core/public'; import { coreRefs } from '../../framework/core_refs'; import { ContentManagementPluginStart } from '../../../../../src/plugins/content_management/public'; import { HOME_CONTENT_AREAS, HOME_PAGE_ID } from '../../plugin_helpers/plugin_overview'; +import { cardConfigs, GettingStartedConfig } from './card_configs'; -// Plugin URLs -const gettingStartedURL = 'observability-gettingStarted'; -const discoverURL = 'data-explorer'; -const metricsURL = 'observability-metrics'; -const tracesURL = 'observability-traces-nav#/traces'; +// Plugin IDs +const alertsPluginID = 'alerting'; +const anomalyPluginID = 'anomalyDetection'; const navigateToApp = (appId: string, path: string) => { coreRefs?.application!.navigateToApp(appId, { @@ -32,94 +30,93 @@ interface HomeProps extends RouteComponentProps, AppAnalyticsCoreDeps { contentManagement: ContentManagementPluginStart; } -interface GettingStartedConfig { - id: string; - order: number; - title: string; - description: string; - footer: string; - url: string; -} - -export const GETTING_STARTED_CONFIG: GettingStartedConfig = { - id: 'getting_started', - order: 1, - title: i18n.translate('observability.overview.card.gettingStarted.title', { - defaultMessage: 'Add your data', - }), - description: 'Get started collecting and analyzing data.', - footer: 'with Getting Started Guide', - url: gettingStartedURL, -}; - -export const DISCOVER_CONFIG: GettingStartedConfig = { - id: 'discover', - order: 2, - title: i18n.translate('observability.overview.card.discover.title', { - defaultMessage: 'Discover insights', - }), - description: 'Uncover insights with raw data exploration.', - footer: 'with Discover', - url: discoverURL, -}; - -export const METRICS_CONFIG: GettingStartedConfig = { - id: 'metrics', - order: 3, - title: i18n.translate('observability.overview.card.metrics.title', { - defaultMessage: 'Metrics', - }), - description: 'Transform logs into actionable visualizations with metrics extraction.', - footer: 'with Metrics', - url: metricsURL, -}; - -export const TRACES_CONFIG: GettingStartedConfig = { - id: 'traces', - order: 4, - title: i18n.translate('observability.overview.card.traces.title', { - defaultMessage: 'Traces', - }), - description: 'Unveil performance bottlenecks with event flow visualization.', - footer: 'with Traces', - url: tracesURL, -}; - -const configs = [GETTING_STARTED_CONFIG, DISCOVER_CONFIG, METRICS_CONFIG, TRACES_CONFIG]; - -configs.map((card) => { - coreRefs.contentManagement?.registerContentProvider({ - id: card.id, - getContent: () => ({ - id: card.id, - kind: 'card', - order: card.order, - description: card.description, - title: card.title, - onClick: () => navigateToApp(card.url, '#/'), - getIcon: () => {}, - getFooter: () => { - return ( - - {card.footer} - - ); +const registerCards = async () => { + let alertsPluginExists = false; + let anomalyPluginExists = false; + + try { + const response = await fetch('../api/status', { + headers: { + 'Content-Type': 'application/json', + 'osd-xsrf': 'true', + 'accept-language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7,zh-TW;q=0.6', + pragma: 'no-cache', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-origin', }, - }), - getTargetArea: () => HOME_CONTENT_AREAS.GET_STARTED, - }); -}); + method: 'GET', + referrerPolicy: 'strict-origin-when-cross-origin', + mode: 'cors', + credentials: 'include', + }); + const data = await response.json(); + + for (const status of data.status.statuses) { + if (status.id.includes(alertsPluginID)) { + console.log('setting alerts plugin true'); + alertsPluginExists = true; + } + if (status.id.includes(anomalyPluginID)) { + anomalyPluginExists = true; + } + } + } catch (error) { + console.error('Error checking plugin installation status:', error); + } + + cardConfigs + .filter((card) => { + if (card.id === 'alerts') { + console.log(alertsPluginExists); + return alertsPluginExists; + } else if (card.id === 'anomaly') { + return anomalyPluginExists; + } + return true; + }) + .map((card: GettingStartedConfig) => { + if (card.id !== 'alerts' || (card.id && alertsPluginExists)) { + coreRefs.contentManagement?.registerContentProvider({ + id: card.id, + getContent: () => ({ + id: card.id, + kind: 'card', + order: card.order, + description: card.description, + title: card.title, + onClick: () => navigateToApp(card.url, '#/'), + getIcon: () => {}, + getFooter: () => { + return ( + + {card.footer} + + ); + }, + }), + getTargetArea: () => HOME_CONTENT_AREAS.GET_STARTED, + }); + } + }); +}; export const Home = ({ ..._props }: HomeProps) => { const homepage = coreRefs.contentManagement?.renderPage(HOME_PAGE_ID); const [ids, setIds] = useState>([]); const [value, setValue] = useState(''); - const [_, setIsRegistered] = useState(false); + const [isRegistered, setIsRegistered] = useState(false); const onChange = (e: React.ChangeEvent) => { setValue(e.target.value.toString()); }; + useEffect(() => { + registerCards(); + }, []); + + useEffect(() => {}, []); + useEffect(() => { coreRefs.savedObjectsClient ?.find({ @@ -128,7 +125,7 @@ export const Home = ({ ..._props }: HomeProps) => { .then((response) => { const dashboardIds = response.savedObjects.map((dashboard) => ({ value: dashboard.id.toString(), - text: dashboard.id.toString(), + text: dashboard.get('title').toString(), })); setIds(dashboardIds); setIsRegistered(true); @@ -136,25 +133,7 @@ export const Home = ({ ..._props }: HomeProps) => { .catch((response) => { console.log(response); }); - }, []); - useEffect(() => { - if (ids.length > 0) { - console.log(ids[0].value); - coreRefs.contentManagement?.registerContentProvider({ - id: '', - getContent: () => ({ - id: 'dashboard_content', - kind: 'dashboard', - order: 1000, - input: { - kind: 'dynamic', - get: () => Promise.resolve(ids[0].value), - }, - }), - getTargetArea: () => HOME_CONTENT_AREAS.DASHBOARD, - }); - } - }, [ids]); + }, [isRegistered]); return (