mirror of https://github.com/grafana/grafana
PublicDashboards: Frontend routing for public dashboards (#48834)
* add isPublic to dashboard * refactor routes to use route group and add placeholder method for sharing apii * add sharing pane and utils for public dashboard config to sharing modal * Sharing modal now persists data through the api * moves ShareDashboard endpoint to new file and starts adding tests * generates mocks. Adds tests for public dashboard feature flag * Adds ability to pass in array of features to enable for the test * test to update public flag on dashboard WIP * Adds mock for SaveDashboardSharingConfig * Fixes tests. Had to use FakeDashboardService * Adds React tests for public dashboards toggle * removes semicolons * refactors SharePublic component to use hooks * rename from `share publicly` to `public dashboard config` * checkpoint. debugging tests. need to verify name changes * checkpoint. test bugs fixed. need to finish returning proper response codes * finish renaming. fix test * Update pkg/api/api.go Co-authored-by: Torkel Ödegaard <torkel@grafana.com> * update backend url * rename internal objects and commands. fix configuration modal labels * add endpoint for retrieving public dashboard configuration and populate the frontend state from it * add test for dashboardCanBePublic * adds backend routes * copy DashboardPage component into component for public dashboards. WIP * adds react routes, and doesnt render main nav bar when viewing a public route * removes extra react route from testing * updates component name * Wrap the original dashboard component so we can pass props relevant to public dashboards, turn kiosk mode on/off, etc * Wraps DashboardPage in PublicDashboardPage component. DashboardPage gets rendered in kiosk mode when public prop is passed. * removes commented out code from exploratory work * Makes public dashboard routes require no auth * extracts helper to own util file to check if were viewing a public page * Hides panel dropdown when its being viewed publicly * formatting * use function from utils file for determining if publicly viewed. If public, hides app notifications, searchwrapper, and commandpalette. * adds unit tests for util function used to see if page is being viewed publicly * cant added annotations to panel when being publicly viewed * removes useless comment * hides backend and frontend pubdash routes behind feature flag * consider feature flag when checking url path to see if on public dashboard * renames function * still render app notifications when in public view * Extract pubdash route logic into own file * fixes failing tests * Determines path using location locationUtils. This covers the case when grafana is being hosted on a subpath. Updates tests. * renames pubdash web route to be more understandable * rename route * fixes failing test * fixes failing test. Needed to update pubdash urls * sets flag on grafana boot config for if viewing public dashboard. Removes hacky check that looks at the url * fixes failing tests. Uses config to determine if viewing public dashboard * renders the blue panel timeInfo on public dashboard panel * Extracts conditional logic for rendering components out into their own functions * removes publicDashboardView check, and uses dashboard meta instead * the timeInfo is always displayed on the panel * After fetch of public dashboard dto, the meta isPublic flag gets set and used to determine if viewing public dashboard for child components. Fixes tests for PanelHeader. * Fixes failing test. Needed to add isPublic flag to dashboard meta. Co-authored-by: Jeff Levin <jeff@levinology.com> Co-authored-by: Torkel Ödegaard <torkel@grafana.com>pull/50444/head
parent
d452322aa8
commit
cfdea1ee30
@ -0,0 +1,11 @@ |
||||
package middleware |
||||
|
||||
import ( |
||||
"github.com/grafana/grafana/pkg/models" |
||||
) |
||||
|
||||
func SetPublicDashboardFlag() func(c *models.ReqContext) { |
||||
return func(c *models.ReqContext) { |
||||
c.IsPublicDashboardView = true |
||||
} |
||||
} |
||||
@ -0,0 +1,13 @@ |
||||
import React from 'react'; |
||||
|
||||
import { GrafanaRouteComponentProps } from '../../../core/navigation/types'; |
||||
|
||||
import DashboardPage, { DashboardPageRouteParams, DashboardPageRouteSearchParams } from './DashboardPage'; |
||||
|
||||
export type Props = GrafanaRouteComponentProps<DashboardPageRouteParams, DashboardPageRouteSearchParams>; |
||||
|
||||
const PublicDashboardPage = (props: Props) => { |
||||
return <DashboardPage isPublic {...props} />; |
||||
}; |
||||
|
||||
export default PublicDashboardPage; |
||||
@ -0,0 +1,42 @@ |
||||
import { render, screen } from '@testing-library/react'; |
||||
import React from 'react'; |
||||
|
||||
import { createEmptyQueryResponse } from '../../../explore/state/utils'; |
||||
import { DashboardModel, PanelModel } from '../../state'; |
||||
|
||||
import { PanelHeader } from './PanelHeader'; |
||||
|
||||
let panelModel = new PanelModel({ |
||||
id: 1, |
||||
gridPos: { x: 1, y: 1, w: 1, h: 1 }, |
||||
type: 'type', |
||||
title: 'title', |
||||
}); |
||||
|
||||
let panelData = createEmptyQueryResponse(); |
||||
|
||||
describe('Panel Header', () => { |
||||
const dashboardModel = new DashboardModel({}, { isPublic: true }); |
||||
it('will render header title but not render dropdown icon when dashboard is being viewed publicly', () => { |
||||
window.history.pushState({}, 'Test Title', '/public-dashboards/abc123'); |
||||
|
||||
render( |
||||
<PanelHeader panel={panelModel} dashboard={dashboardModel} isViewing={false} isEditing={false} data={panelData} /> |
||||
); |
||||
|
||||
expect(screen.getByText('title')).toBeDefined(); |
||||
expect(screen.queryByTestId('panel-dropdown')).toBeNull(); |
||||
}); |
||||
|
||||
it('will render header title and dropdown icon when dashboard is not being viewed publicly', () => { |
||||
const dashboardModel = new DashboardModel({}, { isPublic: false }); |
||||
window.history.pushState({}, 'Test Title', '/d/abc/123'); |
||||
|
||||
render( |
||||
<PanelHeader panel={panelModel} dashboard={dashboardModel} isViewing={false} isEditing={false} data={panelData} /> |
||||
); |
||||
|
||||
expect(screen.getByText('title')).toBeDefined(); |
||||
expect(screen.getByTestId('panel-dropdown')).toBeDefined(); |
||||
}); |
||||
}); |
||||
@ -0,0 +1,24 @@ |
||||
import { SafeDynamicImport } from '../../core/components/DynamicImports/SafeDynamicImport'; |
||||
import { config } from '../../core/config'; |
||||
import { RouteDescriptor } from '../../core/navigation/types'; |
||||
import { DashboardRoutes } from '../../types'; |
||||
|
||||
export const getPublicDashboardRoutes = (): RouteDescriptor[] => { |
||||
if (config.featureToggles.publicDashboards) { |
||||
return [ |
||||
{ |
||||
path: '/public-dashboards/:uid', |
||||
pageClass: 'page-dashboard', |
||||
routeName: DashboardRoutes.Public, |
||||
component: SafeDynamicImport( |
||||
() => |
||||
import( |
||||
/* webpackChunkName: "PublicDashboardPage" */ '../../features/dashboard/containers/PublicDashboardPage' |
||||
) |
||||
), |
||||
}, |
||||
]; |
||||
} |
||||
|
||||
return []; |
||||
}; |
||||
Loading…
Reference in new issue