import { css } from '@emotion/css'; import { useEffect, useState } from 'react'; import { Routes, Route } from 'react-router-dom-v5-compat'; import { DataQueryRequest, DataSourceGetTagKeysOptions, DataSourceGetTagValuesOptions, PageLayoutType, } from '@grafana/data'; import { config, locationService } from '@grafana/runtime'; import { SceneComponentProps, SceneObjectBase, SceneObjectState, UrlSyncContextProvider } from '@grafana/scenes'; import { useStyles2 } from '@grafana/ui/'; import { Page } from 'app/core/components/Page/Page'; import { getClosestScopesFacade, ScopesFacade, ScopesSelector } from 'app/features/scopes'; import { AppChromeUpdate } from '../../core/components/AppChrome/AppChromeUpdate'; import { DataTrail } from './DataTrail'; import { DataTrailsHome } from './DataTrailsHome'; import { getTrailStore } from './TrailStore/TrailStore'; import { HOME_ROUTE, RefreshMetricsEvent, TRAILS_ROUTE } from './shared'; import { getMetricName, getUrlForTrail, newMetricsTrail } from './utils'; export interface DataTrailsAppState extends SceneObjectState { trail: DataTrail; home: DataTrailsHome; } export class DataTrailsApp extends SceneObjectBase { private _scopesFacade: ScopesFacade | null; public constructor(state: DataTrailsAppState) { super(state); this._scopesFacade = getClosestScopesFacade(this); } public enrichDataRequest(): Partial { if (!config.featureToggles.promQLScope) { return {}; } return { scopes: this._scopesFacade?.value, }; } public enrichFiltersRequest(): Partial { if (!config.featureToggles.promQLScope) { return {}; } return { scopes: this._scopesFacade?.value, }; } goToUrlForTrail(trail: DataTrail) { locationService.push(getUrlForTrail(trail)); this.setState({ trail }); } static Component = ({ model }: SceneComponentProps) => { const { trail, home } = model.useState(); return ( {/* The routes are relative to the HOME_ROUTE */} null} subTitle="" > } /> } /> ); }; } function DataTrailView({ trail }: { trail: DataTrail }) { const styles = useStyles2(getStyles); const [isInitialized, setIsInitialized] = useState(false); const { metric } = trail.useState(); useEffect(() => { if (!isInitialized) { if (trail.state.metric !== undefined) { getTrailStore().setRecentTrail(trail); } setIsInitialized(true); } }, [trail, isInitialized]); if (!isInitialized) { return null; } return ( {config.featureToggles.singleTopNav && config.featureToggles.enableScopesInMetricsExplore && ( } /> )} ); } let dataTrailsApp: DataTrailsApp; export function getDataTrailsApp() { if (!dataTrailsApp) { const $behaviors = config.featureToggles.enableScopesInMetricsExplore ? [ new ScopesFacade({ handler: (facade) => { const trail = facade.parent && 'trail' in facade.parent.state ? facade.parent.state.trail : undefined; if (trail instanceof DataTrail) { trail.publishEvent(new RefreshMetricsEvent()); trail.checkDataSourceForOTelResources(); } }, }), ] : undefined; dataTrailsApp = new DataTrailsApp({ trail: newMetricsTrail(), home: new DataTrailsHome({}), $behaviors, }); } return dataTrailsApp; } const getStyles = () => ({ topNavContainer: css({ width: '100%', display: 'flex', flexDirection: 'row', justifyItems: 'flex-start', }), });