diff --git a/public/app/features/dashboard/containers/DashboardPage.tsx b/public/app/features/dashboard/containers/DashboardPage.tsx index bdc6c2acdf4..ef9f5b15212 100644 --- a/public/app/features/dashboard/containers/DashboardPage.tsx +++ b/public/app/features/dashboard/containers/DashboardPage.tsx @@ -12,9 +12,10 @@ import { PageLayoutType } from 'app/core/components/Page/types'; import { createErrorNotification } from 'app/core/copy/appNotification'; import { getKioskMode } from 'app/core/navigation/kiosk'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; -import { PanelModel } from 'app/features/dashboard/state'; +import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; import { dashboardWatcher } from 'app/features/live/dashboard/dashboardWatcher'; -import { KioskMode, StoreState } from 'app/types'; +import { getPageNavFromSlug, getRootContentNavModel } from 'app/features/storage/StorageFolderPage'; +import { DashboardRoutes, KioskMode, StoreState } from 'app/types'; import { PanelEditEnteredEvent, PanelEditExitedEvent } from 'app/types/events'; import { cancelVariables, templateVarsChangedInUrl } from '../../variables/state/actions'; @@ -149,28 +150,7 @@ export class UnthemedDashboardPage extends PureComponent { return; } - // Update page nav - if (!this.pageNav || dashboard.title !== this.pageNav.text) { - this.pageNav = { - text: dashboard.title, - url: locationUtil.getUrlForPartial(this.props.history.location, { - editview: null, - editPanel: null, - viewPanel: null, - }), - }; - } - - // Check if folder changed - if ( - dashboard.meta.folderTitle && - (!this.pageNav.parentItem || this.pageNav.parentItem.text !== dashboard.meta.folderTitle) - ) { - this.pageNav.parentItem = { - text: dashboard.meta.folderTitle, - url: `/dashboards/f/${dashboard.meta.folderUid}`, - }; - } + this.updatePageNav(dashboard); if ( prevProps.match.params.uid !== match.params.uid || @@ -339,6 +319,45 @@ export class UnthemedDashboardPage extends PureComponent { return inspectPanel; } + updatePageNav(dashboard: DashboardModel) { + if (!this.pageNav || dashboard.title !== this.pageNav.text) { + this.pageNav = { + text: dashboard.title, + url: locationUtil.getUrlForPartial(this.props.history.location, { + editview: null, + editPanel: null, + viewPanel: null, + }), + }; + } + + // Check if folder changed + if ( + dashboard.meta.folderTitle && + (!this.pageNav.parentItem || this.pageNav.parentItem.text !== dashboard.meta.folderTitle) + ) { + this.pageNav.parentItem = { + text: dashboard.meta.folderTitle, + url: `/dashboards/f/${dashboard.meta.folderUid}`, + }; + } + + if (this.props.route.routeName === DashboardRoutes.Path) { + const pageNav = getPageNavFromSlug(this.props.match.params.slug!); + if (pageNav?.parentItem) { + this.pageNav.parentItem = pageNav.parentItem; + } + } + } + + getPageProps() { + if (this.props.route.routeName === DashboardRoutes.Path) { + return { navModel: getRootContentNavModel(), pageNav: this.pageNav }; + } else { + return { navId: 'dashboards', pageNav: this.pageNav }; + } + } + render() { const { dashboard, initError, queryParams, isPublic } = this.props; const { editPanel, viewPanel, updateScrollTop } = this.state; @@ -368,8 +387,7 @@ export class UnthemedDashboardPage extends PureComponent { return ( {} -export const StorageFolderPage: FC = (props) => { - const slug = props.match.params.slug; - - const styles = useStyles2(getStyles); +export function StorageFolderPage(props: Props) { + const slug = props.match.params.slug ?? ''; const listing = useAsync((): Promise => { return getGrafanaStorage().list(slug); }, [slug]); - let base = document.location.pathname; - if (!base.endsWith('/')) { - base += '/'; - } - let parent = ''; - const idx = base.lastIndexOf('/', base.length - 2); - if (idx > 0) { - parent = base.substring(0, idx); - } + const childRoot = slug.length > 0 ? `g/${slug}/` : 'g/'; + const pageNav = getPageNavFromSlug(slug); const renderListing = () => { if (listing.value) { @@ -35,8 +27,10 @@ export const StorageFolderPage: FC = (props) => { let name = item; const isFolder = name.indexOf('.') < 0; const isDash = !isFolder && name.endsWith('.json'); + const url = `${childRoot}${name}`; + return ( - + {name} @@ -51,29 +45,37 @@ export const StorageFolderPage: FC = (props) => { return
?
; }; + const navModel = getRootContentNavModel(); + return ( -
- {slug?.length > 0 && ( - <> -

{slug}

- - {parent} - - - - -
- + + {!config.featureToggles.topnav && ( +
+ This page is designed assuming topnav is enabled +
)} {renderListing()} -
+
); -}; +} + +export function getPageNavFromSlug(slug: string) { + const parts = slug.split('/'); + let pageNavs: NavModelItem[] = []; + let url = 'g'; + let lastPageNav: NavModelItem | undefined; + + for (let i = 0; i < parts.length; i++) { + url += `/${parts[i]}`; + pageNavs.push({ text: parts[i], url, parentItem: lastPageNav }); + lastPageNav = pageNavs[pageNavs.length - 1]; + } + + return lastPageNav; +} -const getStyles = (theme: GrafanaTheme2) => ({ - wrapper: css` - margin: 50px; - `, -}); +export function getRootContentNavModel(): NavModel { + return { main: { text: 'C:' }, node: { text: 'Content', url: '/g' } }; +} export default StorageFolderPage; diff --git a/public/app/features/storage/storage.ts b/public/app/features/storage/storage.ts index 3e51e01626f..d51e3ccce43 100644 --- a/public/app/features/storage/storage.ts +++ b/public/app/features/storage/storage.ts @@ -123,6 +123,7 @@ class SimpleStorage implements GrafanaStorage { if (!path.endsWith('.json')) { path += '.json'; } + const result = await backendSrv.get(`/api/storage/read/${path}`); result.uid = path; delete result.id; // Saved with the dev dashboards!