|
|
|
@ -1,11 +1,9 @@ |
|
|
|
|
import { css } from '@emotion/css'; |
|
|
|
|
import React, { useEffect } from 'react'; |
|
|
|
|
import { Route, Switch } from 'react-router-dom'; |
|
|
|
|
|
|
|
|
|
import { GrafanaTheme2, PageLayoutType } from '@grafana/data'; |
|
|
|
|
import { PageLayoutType } from '@grafana/data'; |
|
|
|
|
import { locationService } from '@grafana/runtime'; |
|
|
|
|
import { SceneComponentProps, SceneObjectBase, SceneObjectState, getUrlSyncManager } from '@grafana/scenes'; |
|
|
|
|
import { useStyles2 } from '@grafana/ui'; |
|
|
|
|
import { SceneComponentProps, SceneObjectBase, SceneObjectState, UrlSyncContextProvider } from '@grafana/scenes'; |
|
|
|
|
import { Page } from 'app/core/components/Page/Page'; |
|
|
|
|
|
|
|
|
|
import { DataTrail } from './DataTrail'; |
|
|
|
@ -13,7 +11,7 @@ import { DataTrailsHome } from './DataTrailsHome'; |
|
|
|
|
import { MetricsHeader } from './MetricsHeader'; |
|
|
|
|
import { getTrailStore } from './TrailStore/TrailStore'; |
|
|
|
|
import { HOME_ROUTE, TRAILS_ROUTE } from './shared'; |
|
|
|
|
import { getMetricName, getUrlForTrail, newMetricsTrail } from './utils'; |
|
|
|
|
import { getUrlForTrail, newMetricsTrail } from './utils'; |
|
|
|
|
|
|
|
|
|
export interface DataTrailsAppState extends SceneObjectState { |
|
|
|
|
trail: DataTrail; |
|
|
|
@ -26,13 +24,12 @@ export class DataTrailsApp extends SceneObjectBase<DataTrailsAppState> { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
goToUrlForTrail(trail: DataTrail) { |
|
|
|
|
this.setState({ trail }); |
|
|
|
|
locationService.push(getUrlForTrail(trail)); |
|
|
|
|
this.setState({ trail }); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static Component = ({ model }: SceneComponentProps<DataTrailsApp>) => { |
|
|
|
|
const { trail, home } = model.useState(); |
|
|
|
|
const styles = useStyles2(getStyles); |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
<Switch> |
|
|
|
@ -50,21 +47,7 @@ export class DataTrailsApp extends SceneObjectBase<DataTrailsAppState> { |
|
|
|
|
</Page> |
|
|
|
|
)} |
|
|
|
|
/> |
|
|
|
|
<Route |
|
|
|
|
exact={true} |
|
|
|
|
path={TRAILS_ROUTE} |
|
|
|
|
render={() => ( |
|
|
|
|
<Page |
|
|
|
|
navId="explore/metrics" |
|
|
|
|
pageNav={{ text: getMetricName(trail.state.metric) }} |
|
|
|
|
layout={PageLayoutType.Custom} |
|
|
|
|
> |
|
|
|
|
<div className={styles.customPage}> |
|
|
|
|
<DataTrailView trail={trail} /> |
|
|
|
|
</div> |
|
|
|
|
</Page> |
|
|
|
|
)} |
|
|
|
|
/> |
|
|
|
|
<Route exact={true} path={TRAILS_ROUTE} render={() => <DataTrailView trail={trail} />} /> |
|
|
|
|
</Switch> |
|
|
|
|
); |
|
|
|
|
}; |
|
|
|
@ -84,7 +67,11 @@ function DataTrailView({ trail }: { trail: DataTrail }) { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return <trail.Component model={trail} />; |
|
|
|
|
return ( |
|
|
|
|
<UrlSyncContextProvider scene={trail}> |
|
|
|
|
<trail.Component model={trail} /> |
|
|
|
|
</UrlSyncContextProvider> |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
let dataTrailsApp: DataTrailsApp; |
|
|
|
@ -92,50 +79,10 @@ let dataTrailsApp: DataTrailsApp; |
|
|
|
|
export function getDataTrailsApp() { |
|
|
|
|
if (!dataTrailsApp) { |
|
|
|
|
dataTrailsApp = new DataTrailsApp({ |
|
|
|
|
trail: getInitialTrail(), |
|
|
|
|
trail: newMetricsTrail(), |
|
|
|
|
home: new DataTrailsHome({}), |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return dataTrailsApp; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Get the initial trail for the app to work with based on the current URL |
|
|
|
|
* |
|
|
|
|
* It will either be a new trail that will be started based on the state represented |
|
|
|
|
* in the URL parameters, or it will be the most recently used trail (according to the trail store) |
|
|
|
|
* which has its current history step matching the URL parameters. |
|
|
|
|
* |
|
|
|
|
* The reason for trying to reinitialize from the recent trail is to resolve an issue |
|
|
|
|
* where refreshing the browser would wipe the step history. This allows you to preserve |
|
|
|
|
* it between browser refreshes, or when reaccessing the same URL. |
|
|
|
|
*/ |
|
|
|
|
function getInitialTrail() { |
|
|
|
|
const newTrail = newMetricsTrail(); |
|
|
|
|
|
|
|
|
|
// Set the initial state of the newTrail based on the URL,
|
|
|
|
|
// In case we are initializing from an externally created URL or a page reload
|
|
|
|
|
getUrlSyncManager().initSync(newTrail); |
|
|
|
|
// Remove the URL sync for now. It will be restored on the trail if it is activated.
|
|
|
|
|
getUrlSyncManager().cleanUp(newTrail); |
|
|
|
|
|
|
|
|
|
// If one of the recent trails is a match to the newTrail derived from the current URL,
|
|
|
|
|
// let's restore that trail so that a page refresh doesn't create a new trail.
|
|
|
|
|
const recentMatchingTrail = getTrailStore().findMatchingRecentTrail(newTrail)?.resolve(); |
|
|
|
|
|
|
|
|
|
// If there is a matching trail, initialize with that. Otherwise, use the new trail.
|
|
|
|
|
return recentMatchingTrail || newTrail; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function getStyles(theme: GrafanaTheme2) { |
|
|
|
|
return { |
|
|
|
|
customPage: css({ |
|
|
|
|
padding: theme.spacing(2, 3, 2, 3), |
|
|
|
|
background: theme.isLight ? theme.colors.background.primary : theme.colors.background.canvas, |
|
|
|
|
flexGrow: 1, |
|
|
|
|
display: 'flex', |
|
|
|
|
flexDirection: 'column', |
|
|
|
|
}), |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|